Plane Integration Model
The PlaneIntegration model stores configuration for integrating with Plane.so project management tool, enabling synchronization of projects, work items, and labels.
Schema Definition
model PlaneIntegration {
id String @id @default(uuid())
apiKey String
baseUrl String
workspace String?
projectId String?
isActive Boolean @default(true)
integrationName String?
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
projects Project[]
@@map("plane_integrations")
}
Field Descriptions
Core Configuration
| Field | Type | Description |
|---|---|---|
id | String | UUID primary key |
apiKey | String | Plane.so API key for authentication |
baseUrl | String | Plane.so instance base URL |
workspace | String? | Workspace slug identifier |
projectId | String? | Default project ID for the integration |
Status and Metadata
| Field | Type | Description |
|---|---|---|
isActive | Boolean | Whether the integration is active (default: true) |
integrationName | String? | Human-readable name for the integration |
description | String? | Description of the integration purpose |
createdAt | DateTime | Integration creation timestamp |
updatedAt | DateTime | Last update timestamp |
Relationships
One-to-Many
- projects:
Project[]- Projects synced from this Plane integration
Usage Examples
Create Plane Integration
const integration = await prisma.planeIntegration.create({
data: {
apiKey: "pl_your_api_key_here",
baseUrl: "https://your-workspace.plane.so",
workspace: "your-workspace",
integrationName: "Main Project Sync",
description: "Sync mobile testing projects from Plane.so"
}
});
Update Integration Settings
await prisma.planeIntegration.update({
where: { id: "plane-integration-123" },
data: {
isActive: false,
description: "Temporarily disabled for maintenance"
}
});
Get Active Integrations
const activeIntegrations = await prisma.planeIntegration.findMany({
where: { isActive: true },
include: {
projects: {
where: { isMember: true },
select: {
name: true,
totalWorkItems: true
}
}
}
});
API Key Management
Secure Storage
// Store encrypted API key
const encryptedKey = encrypt(apiKey, process.env.ENCRYPTION_KEY);
await prisma.planeIntegration.create({
data: {
apiKey: encryptedKey, // Store encrypted
// ... other fields
}
});
Key Rotation
// Update API key
await prisma.planeIntegration.update({
where: { id: "plane-integration-123" },
data: {
apiKey: newEncryptedKey,
updatedAt: new Date()
}
});
Integration Testing
Connection Test
async function testPlaneConnection(integrationId: string) {
const integration = await prisma.planeIntegration.findUnique({
where: { id: integrationId }
});
try {
const response = await fetch(`${integration.baseUrl}/api/workspaces/${integration.workspace}/projects`, {
headers: {
'Authorization': `Bearer ${decrypt(integration.apiKey)}`,
'Content-Type': 'application/json'
}
});
return {
success: response.ok,
status: response.status,
projectsCount: response.ok ? (await response.json()).length : 0
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
Webhook Configuration
Setup Webhooks for Real-time Sync
// Configure Plane webhook for real-time updates
const webhookConfig = {
url: `${process.env.APP_URL}/api/webhooks/plane`,
events: [
'work_item.created',
'work_item.updated',
'work_item.deleted',
'label.created',
'label.updated',
'project.updated'
],
secret: generateWebhookSecret()
};
Best Practices
Security
- Encrypt API keys before storage
- Use HTTPS for all Plane API calls
- Implement proper error handling
- Regular key rotation
Performance
- Cache frequently accessed data
- Implement rate limiting
- Use webhooks for real-time updates
- Batch operations when possible
Monitoring
- Track API usage and limits
- Monitor sync success/failure rates
- Log integration health status
- Alert on connection issues