Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions agents-docs/content/community/contributing/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,74 @@ inkeep --version
For more CLI setup options, see the CLI docs:
https://docs.inkeep.com/guides/cli/overview


## Database Error Handling

### Retry Utilities

The `@inkeep/agents-core` package provides retry utilities for handling transient database errors:

```typescript
import { withRetry, withRetryTransaction } from '@inkeep/agents-core';

// Wrap a database operation with automatic retry
const result = await withRetry(
() => db.select().from(users).where(eq(users.id, userId)),
{ context: 'get-user', maxRetries: 3 }
);

// Wrap a transaction with automatic retry
const result = await withRetryTransaction(
db,
async (tx) => {
await tx.insert(logs).values({ action: 'update' });
await tx.update(users).set({ name: 'New Name' });
return tx.select().from(users);
},
{ context: 'update-user-tx' }
);
```

### Retryable Errors

The retry utilities automatically handle these PostgreSQL SQLSTATE errors:

| Category | Codes | Description |
|----------|-------|-------------|
| Serialization | `40001`, `40P01` | Serialization failures and deadlocks |
| Connection | `08000`, `08003`, `08006`, `57P01`, `57P03` | Connection issues and server shutdown |
| Resources | `53000`, `53200`, `53300`, `55P03` | Resource limits (memory, connections, locks) |

### Error Classification Helpers

Use these helpers to handle specific error types:

```typescript
import { isForeignKeyViolation, isSerializationError } from '@inkeep/agents-core';

try {
await db.insert(records).values(data);
} catch (error) {
if (isForeignKeyViolation(error)) {
// Handle missing parent record
}
if (isSerializationError(error)) {
// Transaction conflict — already handled by withRetryTransaction
}
throw error;
}
```

### DAL Boundary Enforcement

A lint script prevents Drizzle ORM imports outside the data access layer:

```bash
pnpm lint:dal-boundary
```

This ensures all database operations go through the DAL, maintaining consistent error handling and scoping.

## Commit Messages

We recommend conventional commit format (not enforced by tooling):
Expand Down
36 changes: 36 additions & 0 deletions agents-docs/content/community/contributing/project-constraints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,41 @@ const validatedCreateAgent = withProjectValidation(db, createAgent);
// Now automatically validates project before creating agent
```


## Type-Safe Scope Helpers

The data access layer uses type-safe scope helpers to enforce consistent project scoping across all queries. This prevents accidental data leakage between tenants and projects.

### ScopedTable Pattern

All DAL queries use scope helper functions instead of manual `eq()` WHERE clauses:

```typescript
import { projectScopedWhere, tenantScopedWhere } from './scope-helpers';

// Instead of manual eq() calls:
// .where(and(eq(table.tenantId, tenantId), eq(table.projectId, projectId)))

// Use type-safe scope helpers:
.where(projectScopedWhere(agents, { tenantId, projectId }))
```

### Available Scope Helpers

| Helper | Scope Level | Required Fields |
|--------|-------------|------------------|
| `tenantScopedWhere` | Tenant | `tenantId` |
| `projectScopedWhere` | Project | `tenantId`, `projectId` |
| `agentScopedWhere` | Agent | `tenantId`, `projectId`, `agentId` |
| `subAgentScopedWhere` | Sub Agent | `tenantId`, `projectId`, `agentId`, `subAgentId` |
| `toolScopedWhere` | Tool | `tenantId`, `projectId`, `toolId` |

### Security Benefits

- **Compile-time safety**: TypeScript enforces that all required scope fields are provided
- **Consistent scoping**: All queries automatically include the correct tenant/project filters
- **Reduced errors**: Prevents accidentally omitting scope conditions

## Implementation Details

### Schema Definition
Expand Down Expand Up @@ -147,6 +182,7 @@ Please create the project first before adding resources to it.
3. **Offer solutions**: When a project doesn't exist, offer to create it
4. **Use transactions**: Ensure atomicity when creating projects and related resources
5. **Test constraints**: Verify that constraints work as expected in tests
6. **Use scope helpers**: Always use `projectScopedWhere` and related helpers instead of manual `eq()` clauses for consistent data isolation

## Migration Guide

Expand Down
Loading