# PocketBase CRUD Module for Wappler Server Connect

A comprehensive Node.js module for Wappler Server Connect that provides full CRUD operations and advanced features for PocketBase integration.

## Features

- **Complete CRUD Operations**: Create, Read, Update, Delete records
- **Authentication**: User login and session management
- **File Management**: Upload files and generate file URLs
- **Advanced Querying**: Filtering, sorting, pagination, and relation expansion
- **Batch Operations**: Perform multiple operations in transactions
- **Health Monitoring**: Check PocketBase instance health
- **Session Management**: Flexible manual token handling and URL persistence
- **Error Handling**: Comprehensive error catching and user-friendly messages

## Installation

1. Copy the module files to your Wappler project:
   ```
   extensions/server_connect/modules/pocketbase.js
   extensions/server_connect/modules/pocketbase.hjson
   ```

2. The PocketBase npm package will be automatically installed when you use any action from this module.

## Quick Start

### 1. Connect to PocketBase

First, establish a connection to your PocketBase instance:

```javascript
// In Wappler Server Connect, add a "Connect to PocketBase" action
// URL: http://127.0.0.1:8090 (or your PocketBase URL)
```

### 2. Authenticate User

```javascript
// Add "Authenticate User" action
// URL: http://127.0.0.1:8090 (required for authentication)
// Email: user@example.com
// Password: userpassword
// Collection: users (default)
```

### 3. Perform CRUD Operations

```javascript
// Create a record
// Collection: posts
// Data: {"title": "My Post", "content": "Hello World"}
// Auth Token: {{authenticate1.token}}

// Get records list
// Collection: posts
// Filter: status = true
// Sort: -created
// Auth Token: {{authenticate1.token}}

// Update a record
// Collection: posts
// ID: record_id_here
// Data: {"title": "Updated Title"}
// Auth Token: {{authenticate1.token}}

// Delete a record
// Collection: posts
// ID: record_id_here
// Auth Token: {{authenticate1.token}}
```

## Available Actions

### Connection & Authentication

#### Connect to PocketBase
- **Purpose**: Initialize connection to PocketBase instance and store URL for other actions
- **Inputs**: 
  - `url` (required): PocketBase URL (e.g., http://127.0.0.1:8090)
  - `authToken` (optional): Pre-existing auth token
- **Output**: Connection status, authentication state, user info, authToken
- **Note**: Stores URL in session for other actions to use automatically

#### Authenticate User
- **Purpose**: Login user with email/password
- **Inputs**:
  - `url` (required): PocketBase URL (must be specified for authentication)
  - `email` (required): User email
  - `password` (required): User password
  - `collection` (optional): Auth collection name (default: "users")
- **Output**: Auth token, user record, success status
- **Note**: Does NOT use URL from Connect action - requires explicit URL

### CRUD Operations

#### Create Record
- **Purpose**: Create new record in collection
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `data` (required): JSON object with record data
  - `authToken` (optional): Authentication token for the request
- **Output**: Created record with ID
- **File Upload**: Include file paths in data object

#### Get Record
- **Purpose**: Retrieve single record by ID
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `id` (required): Record ID
  - `expand` (optional): Relations to expand
  - `fields` (optional): Specific fields to return
  - `authToken` (optional): Authentication token for the request
- **Output**: Record data

#### Get Records List
- **Purpose**: Get paginated list of records
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `page` (optional): Page number (default: 1)
  - `perPage` (optional): Records per page (default: 30)
  - `filter` (optional): Filter expression
  - `sort` (optional): Sort expression
  - `expand` (optional): Relations to expand
  - `fields` (optional): Specific fields to return
  - `authToken` (optional): Authentication token for the request
- **Output**: Paginated results with metadata

#### Get All Records
- **Purpose**: Retrieve all records (batch fetched)
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `filter` (optional): Filter expression
  - `sort` (optional): Sort expression
  - `expand` (optional): Relations to expand
  - `fields` (optional): Specific fields to return
  - `batch` (optional): Batch size (default: 200)
  - `authToken` (optional): Authentication token for the request
- **Output**: All records array

#### Update Record
- **Purpose**: Update existing record
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `id` (required): Record ID
  - `data` (required): JSON object with update data
  - `authToken` (optional): Authentication token for the request
- **Output**: Updated record

#### Delete Record
- **Purpose**: Delete record by ID
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `id` (required): Record ID
  - `authToken` (optional): Authentication token for the request
- **Output**: Success confirmation

### File Operations

#### Get File URL
- **Purpose**: Generate URL for file attached to record
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `collection` (required): Collection name
  - `recordId` (required): Record ID containing file
  - `filename` (required): File name
  - `thumb` (optional): Thumbnail size (e.g., "100x100")
- **Output**: File URL

### Advanced Operations

#### Batch Operations
- **Purpose**: Perform multiple operations in single transaction
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
  - `operations` (required): Array of operations
  - `authToken` (optional): Authentication token for the request
- **Operation Format**:
  ```json
  [
    {"type": "create", "collection": "posts", "data": {...}},
    {"type": "update", "collection": "posts", "id": "123", "data": {...}},
    {"type": "delete", "collection": "posts", "id": "456"}
  ]
  ```
- **Output**: Batch results

#### Health Check
- **Purpose**: Check PocketBase instance health
- **Inputs**:
  - `url` (optional): Leave empty to use URL from Connect action
- **Output**: Health status and data

## Usage Examples

### Basic CRUD Workflow

```javascript
// 1. Connect (stores URL for other actions)
Connect to PocketBase
  URL: http://127.0.0.1:8090

// 2. Authenticate (requires explicit URL)
Authenticate User
  URL: http://127.0.0.1:8090
  Email: {{$_POST.email}}
  Password: {{$_POST.password}}

// 3. Create Record (uses URL from Connect automatically)
Create Record
  Collection: posts
  Data: {
    "title": "{{$_POST.title}}",
    "content": "{{$_POST.content}}",
    "author": "{{authenticate1.user.id}}"
  }
  Auth Token: {{authenticate1.token}}

// 4. Get Records (uses URL from Connect automatically)
Get Records List
  Collection: posts
  Filter: author = '{{authenticate1.user.id}}'
  Sort: -created
  Page: {{$_GET.page || 1}}
  Per Page: 10
  Auth Token: {{authenticate1.token}}
```

### File Upload Example

```javascript
// Create record with file
Create Record
  Collection: posts
  Data: {
    "title": "{{$_POST.title}}",
    "image": "{{$_FILES.image.path}}"  // File path for upload
  }
  Auth Token: {{authenticate1.token}}

// Get file URL
Get File URL
  Collection: posts
  Record ID: {{create1.id}}
  Filename: {{create1.record.image}}
  Thumb: 300x200
```

### Advanced Filtering

```javascript
// Complex filter example
Get Records List
  Collection: posts
  Filter: status = true && created > '2023-01-01' && (category = 'tech' || category = 'news')
  Sort: -created,title
  Expand: author,category
  Fields: id,title,content,created,author.name,category.name
  Auth Token: {{authenticate1.token}}
```

### Batch Operations

```javascript
Batch Operations
  Operations: [
    {
      "type": "create",
      "collection": "posts",
      "data": {"title": "Post 1", "content": "Content 1"}
    },
    {
      "type": "create", 
      "collection": "posts",
      "data": {"title": "Post 2", "content": "Content 2"}
    },
    {
      "type": "update",
      "collection": "posts", 
      "id": "existing_id",
      "data": {"status": "published"}
    }
  ]
  Auth Token: {{authenticate1.token}}
```

## Filter Expressions

PocketBase supports powerful filter expressions:

### Basic Operators
- `=` Equal
- `!=` Not equal
- `>` Greater than
- `>=` Greater than or equal
- `<` Less than
- `<=` Less than or equal
- `~` Like (case insensitive)
- `!~` Not like

### Logical Operators
- `&&` AND
- `||` OR

### Examples
```javascript
// Simple filters
"status = true"
"created > '2023-01-01'"
"title ~ 'hello'"

// Complex filters
"status = true && created > '2023-01-01'"
"(category = 'tech' || category = 'news') && status = true"
"author.name ~ 'john' && created >= '2023-01-01'"
```

## Sort Expressions

Sort records using field names:

```javascript
// Ascending
"created"
"title"

// Descending (prefix with -)
"-created"
"-title"

// Multiple fields
"status,-created,title"
```

## Error Handling

The module provides comprehensive error handling:

- Connection errors
- Authentication failures
- Validation errors
- Network timeouts
- Invalid data formats

All errors are returned in a consistent format with descriptive messages.

## Session Management

The module provides flexible session management:

### URL Management
- **Connect Action**: Stores PocketBase URL in session for other actions
- **Automatic URL**: All actions (except Authenticate) use stored URL when URL field is empty
- **Manual Override**: Specify URL in any action to override stored URL

### Authentication Token Management
- **Manual Control**: You control when and how to store authentication tokens
- **No Automatic Storage**: Authentication tokens are returned but not automatically saved
- **Explicit Tokens**: Pass auth tokens explicitly in each action that needs authentication

### Recommended Workflow
```javascript
// 1. Connect (stores URL)
Connect to PocketBase
  URL: http://127.0.0.1:8090

// 2. Authenticate (requires explicit URL)
Authenticate User
  URL: http://127.0.0.1:8090
  Email: {{$_POST.email}}
  Password: {{$_POST.password}}

// 3. Store token manually (optional - use Wappler session actions)
Set Session Variable
  Name: auth_token
  Value: {{authenticate1.token}}

// 4. Use in other actions (URL automatic, token manual)
Create Record
  Collection: posts
  Data: {...}
  Auth Token: {{$_SESSION.auth_token}}
```

## Security Features

- Secure token handling
- Input validation
- File upload security
- SQL injection prevention
- XSS protection

## Requirements

- Wappler with Node.js server model
- PocketBase instance (v0.15.0+)
- Node.js 14+

## Support

For issues and questions:
1. Check PocketBase documentation: https://pocketbase.io/docs/
2. Review Wappler Server Connect documentation
3. Verify your PocketBase instance is running and accessible

## License

This module is provided as-is for use with Wappler projects.
