# ARP - Agent Resource Platform

A GraphQL-based coordination system for users and agents to collaborate on services, tasks, and workflows.

## Overview

ARP (Agent Resource Platform) is a coordination backend that enables human users and AI agents to work together on shared services. It provides:

- **User Management** - Role-based access control with fine-grained permissions
- **Service Coordination** - Create and manage services with multiple participants
- **Task Management** - Assignable work items with status tracking
- **Notes** - Attach notes to services for context
- **Messaging** - Real-time chat channels between participants
- **Workflow Engine** - DAG-based workflow definitions with automatic task creation and dependency management

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                      GraphQL API                            │
│  (gqlgen - schema-first, type-safe resolvers)               │
├─────────────────────────────────────────────────────────────┤
│                    Auth Middleware                          │
│  (JWT tokens, permission checks)                            │
├─────────────────────────────────────────────────────────────┤
│                     GORM Models                             │
│  User → Role → Permission                                   │
│  Service → Task → TaskStatus                                │
│  Channel → Message                                          │
│  Note                                                       │
├─────────────────────────────────────────────────────────────┤
│                   SQLite Database                           │
│  (arp.db - can be swapped for PostgreSQL/MySQL)             │
└─────────────────────────────────────────────────────────────┘
```

## Quick Start

### Prerequisites

- Go 1.21+
- SQLite3 (or modify for PostgreSQL/MySQL)

### Running the Server

```bash
# Clone and run
go run server.go

# Server starts on http://localhost:8080
```

### Running Tests

```bash
go test ./... -v
```

## API Interaction with Bash

### 1. Start the Server

```bash
go run server.go &
# Server runs on http://localhost:8080
```

### 2. Inspect the GraphQL Schema

Use GraphQL introspection to discover the API schema:

```bash
# Get all types in the schema
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { types { name kind description fields { name type { name kind ofType { name } } } } } }"}' | jq

# Get all queries and mutations
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"{ __schema { queryType { fields { name description } } mutationType { fields { name description } } } }"}' | jq
```

### 3. Initialize Database with Seed Data

Run the SQL bootstrap script to create permissions, roles, task statuses, and an admin user:

```bash
# Initialize the database with seed data
sqlite3 arp.db < init.sql

# Verify the data was created
sqlite3 arp.db "SELECT name FROM roles;"
# Output:
# admin
# manager
# user

sqlite3 arp.db "SELECT email FROM users;"
# Output:
# admin@example.com
```

The `init.sql` script creates:
- **36 permissions** covering all CRUD operations for each entity type
- **3 roles**: admin (full access), manager (service/task management), user (read-only + notes/messages)
- **1 admin user** with email `admin@example.com` and password `secret123`
- **6 task statuses**: open, in_progress, blocked, review, done, cancelled

### 4. Login and Get JWT Token

```bash
# Login to get JWT token
TOKEN=$(curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -d '{"query":"mutation { login(email: \"admin@example.com\", password: \"secret123\") { token user { email roles { name } } } }"}' | jq -r '.data.login.token')

echo "Token: $TOKEN"
```

### 5. Pull List of Services (Authenticated)

```bash
# Get all services with authentication
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"{ services { id name description createdAt participants { email } tasks { title status { label } } } }"}' | jq
```

### 6. Create a Service

```bash
# Create a new service
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"mutation { createService(input: {name: \"Project Alpha\", description: \"New project\", createdById: \"1\", participants: [\"1\"]}) { id name } }"}' | jq
```

### 7. Query Single Service by ID

```bash
# Get a specific service
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"{ service(id: \"1\") { id name description createdBy { email } participants { email } tasks { id title priority status { code label } } } }"}' | jq
```

## Authentication & Authorization

### Permission System

The system uses a hierarchical permission model:

```
User ─┬─ has many ─→ Role ─┬─ has many ─→ Permission
      │                    │
      └─ e.g., "admin"     └─ e.g., "service:create"
```

### Required Permissions for Operations

| Operation | Required Permission |
|-----------|---------------------|
| Update User | `user:update` |
| Delete User | `user:delete` |
| Update Task | `task:update` |
| Delete Task | `task:delete` |
| Update Note | `note:update` |
| Delete Note | `note:delete` |
| Update Service | `service:update` |
| Delete Service | `service:delete` |
| ... | ... |

### Using Authentication in Requests

```bash
# Include JWT token in Authorization header
curl -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"query":"..."}'
```

## GraphQL Schema Overview

### Core Types

- **User** - Agent or human account
- **Role** - Groups of permissions
- **Permission** - Fine-grained access control (e.g., `task:create`)
- **Service** - Coordination unit with participants and tasks
- **Task** - Assignable work item with status
- **TaskStatus** - Workflow states (open, in_progress, done)
- **Note** - Notes attached to services
- **Channel** - Chat between participants
- **Message** - Individual chat messages

### Key Queries

```graphql
type Query {
  users: [User!]!
  user(id: ID!): User
  services: [Service!]!
  service(id: ID!): Service
  tasks: [Task!]!
  task(id: ID!): Task
  roles: [Role!]!
  permissions: [Permission!]!
  # ... more queries
}
```

### Key Mutations

```graphql
type Mutation {
  login(email: String!, password: String!): AuthPayload!
  createUser(input: NewUser!): User!
  createService(input: NewService!): Service!
  createTask(input: NewTask!): Task!
  # ... more mutations
}
```

## Workflow Engine

The workflow engine enables you to define complex multi-step processes as JSON-based DAGs (Directed Acyclic Graphs). Each node in the DAG represents a task or decision point, and dependencies between nodes are automatically resolved.

### Workflow Definition Format

Workflows are defined as JSON with a `nodes` object where each key is a unique node identifier:

```json
{
  "nodes": {
    "start": {
      "type": "task",
      "title": "Initial Review",
      "content": "Review the initial request",
      "assignee": "1",
      "dependsOn": []
    },
    "analysis": {
      "type": "task",
      "title": "Data Analysis",
      "content": "Analyze the data",
      "assignee": "2",
      "dependsOn": ["start"]
    },
    "approval": {
      "type": "task",
      "title": "Manager Approval",
      "content": "Get manager approval",
      "assignee": "3",
      "dependsOn": ["analysis"]
    },
    "end": {
      "type": "task",
      "title": "Complete",
      "content": "Mark workflow as complete",
      "assignee": "1",
      "dependsOn": ["approval"]
    }
  }
}
```

### Workflow Permissions

| Operation | Required Permission |
|-----------|---------------------|
| Create Workflow Template | `workflow:create` |
| Update Workflow Template | `workflow:manage` |
| Delete Workflow Template | `workflow:manage` |
| Start Workflow | `workflow:start` |
| Cancel Workflow | `workflow:manage` |
| Retry Node | `workflow:intervene` |
| View Workflows | `workflow:view` |

### Workflow Node Types

| Type | Description |
|------|-------------|
| `task` | Creates a task for a user to complete |
| `condition` | Evaluates conditions to determine next steps |
| `parallel` | Spawns multiple concurrent branches |
| `join` | Waits for multiple branches to complete |
| `trigger` | Starts the workflow automatically |

### Automatic Task Completion Integration

When a task associated with a workflow node is marked as "done", the workflow engine automatically:
1. Marks the corresponding node as completed
2. Evaluates downstream dependencies
3. Creates tasks for newly ready nodes

This enables workflows to progress automatically as users complete their assigned tasks.

### Workflow API Examples

```bash
# Create a workflow template
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "query": "mutation { createWorkflowTemplate(input: {name: \"Onboarding\", description: \"New employee onboarding\", definition: \"{\\\"nodes\\\":{\\\"start\\\":{\\\"type\\\":\\\"task\\\",\\\"title\\\":\\\"Welcome\\\",\\\"content\\\":\\\"Send welcome email\\\",\\\"assignee\\\":\\\"1\\\",\\\"dependsOn\\\":[]}}}\"}) { id name }"
  }' | jq

# Start a workflow instance
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "query": "mutation { startWorkflow(templateId: \"1\", input: {serviceId: \"1\", context: \"New hire onboarding\"}) { id status template { name } } }"
  }' | jq

# Get all workflow instances
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"{ workflowInstances { id status template { name } service { name } } }"}' | jq

# Retry a failed workflow node
curl -s -X POST http://localhost:8080/query \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"query":"mutation { retryWorkflowNode(nodeId: \"1\") { id nodeKey status retryCount } }"}' | jq
```


## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `JWT_SECRET` | `your-secret-key-change-in-production` | Secret for JWT signing |
