> ## Documentation Index
> Fetch the complete documentation index at: https://cona.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Actors

# Actors

An **actor** in CONA represents any entity that can perform actions within an organization. Actors provide a unified way to track and attribute actions across the system.

## Types of Actors

### User Actors

* **Purpose**: Represent a person within an organization
* **Creation**: Created when a user joins an organization
* **Identification**: Has `user_id` populated, uses `label` field
* **Usage**: Authentication, permissions, user actions
* **Example**: `actor_123` with `user_id: "user_456"` and `label: "John Doe"`

### App Actors

* **Purpose**: Represent an app/integration within an organization
* **Creation**: Created when an app is installed
* **Identification**: Has `user_id` as null, uses `apps_label` field
* **Usage**: System actions, automated processes, app-generated data
* **Example**: `actor_789` with `user_id: null` and `apps_label: "shopify"`

## Database Structure

```sql theme={null}
-- Actors table (from actual schema)
model actors {
    id                String       @id @default(cuid())
    user_id           String?      -- Links to users table (for user actors only)
    label             String       -- Used for user actors
    apps_label        String?      -- Used for app actors  
    org_id            String       -- Organization context
    avatar_url        String?      -- For user actors
    logo_url          String?      -- For app actors
    -- ... other fields
    
    @@unique([apps_label, org_id])
    @@unique([label, org_id])
    @@unique([user_id, org_id])
}
```

## Key Distinctions

**User Actors**:

* `user_id` is populated
* Uses `label` field for name
* Has `avatar_url` for profile picture
* Unique constraint on `[user_id, org_id]` and `[label, org_id]`

**App Actors**:

* `user_id` is null
* Uses `apps_label` field for app identifier
* Has `logo_url` for app logo
* Unique constraint on `[apps_label, org_id]`

## Important Distinction for Analytics

When tracking user actions in PostHog, always use the **authenticated user's actor ID**:

```typescript theme={null}
// ✅ Correct - track user action
const { actorId: userActorId } = await requireAuth();
await trackEventWithAuth(userActorId, organizationId, organizationName, "action_performed", {});

// ❌ Wrong - using app actor from data
const appInstallation = { actor_id: "app_actor_123" }; // This could be an app actor!
await trackEventWithAuth(appInstallation.actor_id, ...); // This would attribute action to the app!
```

## Key Takeaway

* **User actors**: Have `user_id` populated, for tracking human actions and analytics
* **App actors**: Have `user_id` as null, for system/automated actions and data attribution
* **Always verify**: Check if `user_id` is populated to determine actor type when tracking events
