# @bangstack/auth-clerk

Clerk authentication workflow template for Bangstack - a complete, production-ready authentication system using [Clerk](https://clerk.com).

## Features

- Complete user authentication flow (signup, login, logout)
- Email verification
- Password reset
- Session management
- Event-driven architecture
- TypeScript type definitions
- React components with Tailwind CSS
- Production-ready database models

## Installation

```bash
npm install @bangstack/auth-clerk
```

## Setup

1. **Create a Clerk account** at [https://clerk.com](https://clerk.com)

2. **Get your API keys** from the Clerk dashboard

3. **Add environment variables** to your `.env` file:
   ```env
   CLERK_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxx
   CLERK_SECRET_KEY=sk_test_xxxxxxxxxxxxx
   CLERK_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx  # Optional
   ```

4. **Reference in your `bang.yaml`** - See usage examples below

5. **Generate your application**:
   ```bash
   bang generate
   ```

## Usage

### Basic Usage - Import Everything

```yaml
# bang.yaml
workflow:
  id: my-app
  version: 1.0.0
  name: My Application

technology:
  backend:
    framework: express
    language: typescript
  frontend:
    framework: react
    styling: tailwind

# Import all models
models:
  User:
    $ref: 'node_modules/@bangstack/auth-clerk/models/user.yaml'
  Session:
    $ref: 'node_modules/@bangstack/auth-clerk/models/session.yaml'

# Import all workflows
workflows:
  user-signup:
    $ref: 'node_modules/@bangstack/auth-clerk/workflows/signup.yaml'
  user-login:
    $ref: 'node_modules/@bangstack/auth-clerk/workflows/login.yaml'
  user-logout:
    $ref: 'node_modules/@bangstack/auth-clerk/workflows/logout.yaml'

# Import events
events:
  user_registered:
    $ref: 'node_modules/@bangstack/auth-clerk/events/auth-events.yaml#/user_registered'
  user_logged_in:
    $ref: 'node_modules/@bangstack/auth-clerk/events/auth-events.yaml#/user_logged_in'
  user_logged_out:
    $ref: 'node_modules/@bangstack/auth-clerk/events/auth-events.yaml#/user_logged_out'

# Import components
components:
  SignUpForm:
    $ref: 'node_modules/@bangstack/auth-clerk/components/sign-up-form.yaml'
```

### Selective Import - Cherry Pick What You Need

```yaml
# Only import the User model and signup workflow
models:
  User:
    $ref: 'node_modules/@bangstack/auth-clerk/models/user.yaml'

workflows:
  user-signup:
    $ref: 'node_modules/@bangstack/auth-clerk/workflows/signup.yaml'
```

### Extend and Customize

You can extend the imported models with your own fields:

```yaml
models:
  # Import base User model
  User:
    $ref: 'node_modules/@bangstack/auth-clerk/models/user.yaml'
    # Add custom fields
    fields:
      - name: subscription_tier
        type: enum
        constraints:
          values: [free, pro, enterprise]
          default: free
      - name: company_name
        type: string
        constraints:
          required: false

  # Your own custom model that references User
  Project:
    name: Project
    fields:
      - name: id
        type: string
        constraints:
          primary: true
      - name: user_id
        type: string
        constraints:
          foreign_key: User.id
      - name: name
        type: string
```

## What Gets Generated

When you use this template and run `bang generate`, you'll get:

### Backend (TypeScript/Express)

```
backend/
├── src/
│   ├── models/
│   │   ├── User.ts          # Prisma/Drizzle User model
│   │   └── Session.ts       # Session model
│   ├── routes/
│   │   └── auth.ts          # Auth routes (/signup, /login, /logout)
│   ├── middleware/
│   │   └── clerkAuth.ts     # Clerk authentication middleware
│   ├── events/
│   │   ├── types.ts         # TypeScript event types
│   │   ├── eventBus.ts      # Redis event bus
│   │   └── handlers/
│   │       └── authHandlers.ts
│   └── workflows/
│       ├── signup.ts
│       ├── login.ts
│       └── logout.ts
```

### Frontend (React + Tailwind)

```
frontend/
├── src/
│   ├── components/
│   │   └── auth/
│   │       ├── SignUpForm.tsx    # Styled signup form
│   │       ├── SignInForm.tsx    # Styled login form
│   │       └── UserButton.tsx    # User menu/logout
│   ├── hooks/
│   │   └── useAuth.ts            # Authentication hook
│   └── pages/
│       ├── SignUp.tsx
│       ├── SignIn.tsx
│       └── Dashboard.tsx         # Protected route example
```

### Database Schema (Prisma)

```prisma
model User {
  id                String    @id @default(cuid())
  clerkId           String    @unique
  email             String    @unique
  emailVerified     Boolean   @default(false)
  firstName         String?
  lastName          String?
  profileImageUrl   String?
  phoneNumber       String?
  phoneVerified     Boolean   @default(false)
  metadata          Json      @default("{}")
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt
  lastSignInAt      DateTime?

  sessions          Session[]
}

model Session {
  id                String    @id @default(cuid())
  clerkSessionId    String    @unique
  userId            String
  status            SessionStatus
  clientId          String
  lastActiveAt      DateTime  @default(now())
  expireAt          DateTime
  abandonAt         DateTime?
  createdAt         DateTime  @default(now())
  updatedAt         DateTime  @updatedAt

  user              User      @relation(fields: [userId], references: [id])
}

enum SessionStatus {
  active
  expired
  revoked
  abandoned
}
```

## Available Templates

### Models

- **user.yaml** - Complete User model with Clerk fields
- **session.yaml** - Session management model

### Workflows

- **signup.yaml** - User registration flow
- **login.yaml** - User authentication flow
- **logout.yaml** - User sign-out flow

### Events

All events defined in `events/auth-events.yaml`:

- `user_registered` - New user account created
- `user_logged_in` - User successfully authenticated
- `user_logged_out` - User signed out
- `email_verified` - Email address verified
- `password_reset_requested` - Password reset initiated
- `password_changed` - Password was changed

### Components

- **sign-up-form.yaml** - Complete signup form with validation

## Event Handlers

Each event comes with pre-defined handlers. For example, `user_registered` triggers:

1. **send-welcome-email** (immediate) - Welcome email to new users
2. **create-onboarding-tasks** (immediate) - Initialize onboarding workflow
3. **track-registration-analytics** (async) - Record registration metrics

You can customize these handlers or add your own.

## Authentication Flow

### Signup Flow
```
User fills form → Clerk API → Create DB record → Send verification email → Create session → Redirect
```

### Login Flow
```
User submits credentials → Clerk authenticates → Update last login → Emit event → Redirect
```

### Logout Flow
```
Revoke Clerk session → Update DB → Emit event → Clear client state → Redirect
```

## Configuration

### Required Environment Variables

```env
CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx
```

### Optional Environment Variables

```env
CLERK_WEBHOOK_SECRET=whsec_xxxxx  # For webhooks
```

### Clerk Dashboard Setup

1. Enable Email/Password authentication
2. Configure email templates
3. Set up webhooks (optional)
4. Configure session settings

## Advanced Usage

### Custom Event Handlers

```yaml
events:
  user_registered:
    $ref: 'node_modules/@bangstack/auth-clerk/events/auth-events.yaml#/user_registered'
    # Add custom handlers
    handlers:
      - name: assign-default-workspace
        trigger: immediate
        implementation:
          action: database_insert
          table: workspaces
          data:
            user_id: "{{user.id}}"
            name: "My Workspace"
```

### Protected Routes

```yaml
api:
  endpoints:
    - path: /api/projects
      method: GET
      auth_required: true      # Requires Clerk authentication
      handler: getProjects
```

### Custom Middleware

```yaml
stack:
  api:
    type: backend
    technology: typescript/express
    middleware:
      - clerk_auth          # Automatically included
      - rate_limit          # Add your own
      - custom_logging
```

## Package Contents

```
@bangstack/auth-clerk/
├── models/
│   ├── user.yaml
│   └── session.yaml
├── workflows/
│   ├── signup.yaml
│   ├── login.yaml
│   └── logout.yaml
├── events/
│   └── auth-events.yaml
├── components/
│   └── sign-up-form.yaml
├── index.yaml
├── package.json
└── README.md
```

## Examples

See the [demo-bang.yaml](./demo-bang.yaml) for a complete example of building a SaaS app with Clerk authentication.

## Contributing

Contributions welcome! Please open an issue or PR at [https://github.com/bangstack/templates-auth-clerk](https://github.com/bangstack/templates-auth-clerk)

## License

MIT

## Resources

- [Bangstack Documentation](https://github.com/mogullabs/bangstack)
- [Clerk Documentation](https://clerk.com/docs)
- [Workflow Reference System ($ref)](https://github.com/mogullabs/bangstack/blob/main/docs/REFERENCE-RESOLUTION.md)

## Support

- GitHub Issues: https://github.com/bangstack/templates-auth-clerk/issues
- Discord: https://discord.gg/bangstack
- Email: support@bangstack.dev
