npm package: @personql/node
Description: PersonQL SDK for Node.js server environments
Author: PersonQL Team
Latest version: 1.0.3
Deprecated: DEPRECATED: This package is no longer needed. Use @personql/core directly for server-side JWT verification with the new jose-based implementation, or use @personql/nextjs for Next.js applications. See https://docs.personql.com for migration guide.

# PersonQL Node.js SDK

Server-side SDK for PersonQL authentication, user management, and analytics in Node.js environments.

## Features

- 🔐 **Server-side Authentication** - Validate tokens and manage sessions
- 👥 **User Management** - Create, update, and manage users from your backend
- 📊 **Server-side Analytics** - Track events and user behavior from your server
- 🚀 **Bulk Operations** - Efficient batch processing for large datasets
- 💾 **Admin Functions** - Export data and generate analytics reports
- ⚡ **High Performance** - Optimized for server environments

## Installation

```bash
npm install @personql/node
# or
yarn add @personql/node
```

## Quick Start

```javascript
const { PersonQLServer } = require('@personql/node');

const personql = new PersonQLServer({
  apiKey: process.env.PERSONQL_API_KEY,
});

// All requests will use the gateway-worker URL automatically.

// Create a user
const user = await personql.createUser({
  email: 'user@example.com',
  firstName: 'John',
  lastName: 'Doe',
  role: 'user',
});

// Track server-side events
await personql.trackUserEvent(user.id, 'user_created', {
  source: 'admin_panel',
  timestamp: new Date(),
});
```

## Configuration

```javascript
const personql = new PersonQLServer({
  apiKey: 'your-api-key', // Required: Your PersonQL API key
  timeout: 30000, // Optional: Request timeout in ms (default: 30000)
});
```

## User Management

### Create Users

```javascript
// Single user
const user = await personql.createUser({
  email: 'user@example.com',
  firstName: 'John',
  lastName: 'Doe',
  role: 'user',
  metadata: {
    department: 'Engineering',
    joinDate: '2024-01-01',
  },
});

// Bulk create users
const users = await personql.bulkCreateUsers([
  { email: 'user1@example.com', firstName: 'John', role: 'user' },
  { email: 'user2@example.com', firstName: 'Jane', role: 'admin' },
  { email: 'user3@example.com', firstName: 'Bob', role: 'user' },
]);
```

### Retrieve and Update Users

```javascript
// Get user by ID
const user = await personql.getUser('user-id-123');

// Update user
const updatedUser = await personql.updateUser('user-id-123', {
  firstName: 'Johnny',
  metadata: {
    lastLogin: new Date().toISOString(),
  },
});

// Delete user
const success = await personql.deleteUser('user-id-123');
```

### Export Users

```javascript
// Export all users
const allUsers = await personql.exportUsers();

// Export with filters
const adminUsers = await personql.exportUsers({
  role: 'admin',
  createdAfter: '2024-01-01',
});
```

## Authentication

### Token Validation

```javascript
// Validate user token (for API middleware)
const user = await personql.validateToken(tokenFromRequest);

if (user) {
  console.log('Authenticated user:', user.email);
} else {
  console.log('Invalid token');
}
```

### Session Management

```javascript
// Create server session
const sessionToken = await personql.createSession('user-id-123');

// Revoke session
const revoked = await personql.revokeSession(sessionToken);
```

## Event Tracking

### Individual Events

```javascript
// Track user-specific events
await personql.trackUserEvent('user-id-123', 'purchase_completed', {
  amount: 99.99,
  currency: 'USD',
  productId: 'prod-456',
  paymentMethod: 'credit_card',
});

// Track anonymous events
await personql.trackEvent({
  event: 'api_call',
  properties: {
    endpoint: '/api/users',
    method: 'GET',
    responseTime: 150,
    statusCode: 200,
  },
  anonymousId: 'anon-789',
});
```

### Bulk Event Tracking

```javascript
// Efficient bulk tracking for high-volume scenarios
const events = [
  {
    event: 'page_view',
    userId: 'user-1',
    properties: { page: '/dashboard', loadTime: 1200 },
  },
  {
    event: 'button_click',
    userId: 'user-2',
    properties: { button: 'subscribe', location: 'header' },
  },
  {
    event: 'api_call',
    properties: { endpoint: '/api/data', method: 'POST' },
  },
];

await personql.bulkTrackEvents(events);
```

## Analytics and Reporting

### Generate Analytics Reports

```javascript
// Get analytics for date range
const analytics = await personql.getAnalytics(
  new Date('2024-01-01'),
  new Date('2024-01-31'),
  {
    groupBy: 'day',
    events: ['purchase_completed', 'user_signup'],
    userSegment: 'premium',
  }
);

console.log('Monthly analytics:', analytics);
```

## Express.js Middleware

```javascript
const express = require('express');
const { PersonQLServer } = require('@personql/node');

const app = express();
const personql = new PersonQLServer({
  apiKey: process.env.PERSONQL_API_KEY,
});

// Authentication middleware
async function authenticateUser(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({ error: 'No token provided' });
  }

  const user = await personql.validateToken(token);

  if (!user) {
    return res.status(401).json({ error: 'Invalid token' });
  }

  req.user = user;
  next();
}

// Protected route
app.get('/api/profile', authenticateUser, (req, res) => {
  res.json({ user: req.user });
});

// Track API usage
app.use('/api/*', async (req, res, next) => {
  const startTime = Date.now();

  res.on('finish', async () => {
    const responseTime = Date.now() - startTime;

    await personql.trackEvent({
      event: 'api_request',
      properties: {
        endpoint: req.path,
        method: req.method,
        statusCode: res.statusCode,
        responseTime,
        userAgent: req.headers['user-agent'],
      },
      userId: req.user?.id,
    });
  });

  next();
});
```

## Next.js API Routes

```javascript
// pages/api/users/index.js
import { PersonQLServer } from '@personql/node';

const personql = new PersonQLServer({
  apiKey: process.env.PERSONQL_API_KEY,
});

export default async function handler(req, res) {
  if (req.method === 'POST') {
    // Create user
    try {
      const user = await personql.createUser(req.body);

      // Track user creation
      await personql.trackUserEvent(user.id, 'user_created', {
        source: 'api',
        ip: req.connection.remoteAddress,
      });

      res.status(201).json({ user });
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
  } else if (req.method === 'GET') {
    // List users with pagination
    const users = await personql.exportUsers({
      limit: req.query.limit || 10,
      offset: req.query.offset || 0,
    });

    res.json({ users });
  }
}
```

## Error Handling

```javascript
try {
  const user = await personql.createUser({
    email: 'invalid-email',
    firstName: 'John',
  });
} catch (error) {
  if (error.message.includes('PersonQL API Error: 400')) {
    console.log('Validation error:', error.message);
  } else if (error.message.includes('PersonQL Request Failed')) {
    console.log('Network error:', error.message);
  } else {
    console.log('Unknown error:', error.message);
  }
}
```

## Health Monitoring

```javascript
// Health check endpoint
app.get('/health', async (req, res) => {
  const isHealthy = await personql.healthCheck();

  if (isHealthy) {
    res.json({ status: 'healthy', service: 'personql' });
  } else {
    res.status(503).json({ status: 'unhealthy', service: 'personql' });
  }
});
```

## Environment Variables

```bash
# Required
PERSONQL_API_KEY=your-api-key-here

# Optional
PERSONQL_TIMEOUT=30000
NODE_ENV=production
```

## TypeScript Support

```typescript
import { PersonQLServer, CreateUserRequest, User } from '@personql/node';

const personql = new PersonQLServer({
  apiKey: process.env.PERSONQL_API_KEY!,
});

const userData: CreateUserRequest = {
  email: 'user@example.com',
  firstName: 'John',
  lastName: 'Doe',
  role: 'user',
};

const user: User = await personql.createUser(userData);
```

## Performance Tips

1. **Use Bulk Operations**: For high-volume scenarios, use `bulkCreateUsers()` and `bulkTrackEvents()`
2. **Implement Caching**: Cache user validation results for better performance
3. **Async Processing**: Track events asynchronously to avoid blocking requests
4. **Connection Pooling**: Reuse the PersonQLServer instance across requests

## API Reference

### PersonQLServer Class

#### Constructor

- `new PersonQLServer(config: NodeConfig)`

#### User Methods

- `createUser(userData: CreateUserRequest): Promise<User>`
- `getUser(userId: string): Promise<User | null>`
- `updateUser(userId: string, updates: Partial<User>): Promise<User>`
- `deleteUser(userId: string): Promise<boolean>`
- `bulkCreateUsers(users: CreateUserRequest[]): Promise<User[]>`
- `exportUsers(filters?: Record<string, any>): Promise<User[]>`

#### Authentication Methods

- `validateToken(token: string): Promise<User | null>`
- `createSession(userId: string): Promise<string>`
- `revokeSession(sessionToken: string): Promise<boolean>`

#### Event Tracking Methods

- `trackEvent(event: ServerEvent): Promise<boolean>`
- `trackUserEvent(userId: string, eventName: string, properties?: Record<string, any>): Promise<boolean>`
- `bulkTrackEvents(events: ServerEvent[]): Promise<boolean>`

#### Analytics Methods

- `getAnalytics(startDate: Date, endDate: Date, filters?: Record<string, any>): Promise<any>`

#### Utility Methods

- `healthCheck(): Promise<boolean>`

## License

MIT License - see LICENSE file for details.