koan-entity-first
Entity<T> patterns, GUID v7 auto-generation, static methods vs manual repositories
Best use case
koan-entity-first is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Entity<T> patterns, GUID v7 auto-generation, static methods vs manual repositories
Teams using koan-entity-first should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/koan-entity-first/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How koan-entity-first Compares
| Feature / Agent | koan-entity-first | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Entity<T> patterns, GUID v7 auto-generation, static methods vs manual repositories
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Koan Entity-First Development
## Core Principle
**Entity<T> replaces manual repositories.** Every entity is self-aware and self-persisting. This pattern eliminates repository boilerplate while maintaining provider transparency.
## Revolutionary Approach
- **GUID v7 Auto-Generation**: IDs generated automatically with chronological ordering
- **Instance Methods**: `await entity.Save()`, `await entity.Remove()`
- **Static Queries**: `await Entity.All()`, `await Entity.Get(id)`, `await Entity.Query()`
- **Provider Agnostic**: Same code works across SQL, NoSQL, Vector, JSON stores
## Quick Reference Card
### Basic Operations
```csharp
// Create entity
public class Todo : Entity<Todo>
{
public string Title { get; set; } = "";
public bool Completed { get; set; }
// Id automatically generated as GUID v7 on first access
}
// Save (create or update)
var todo = new Todo { Title = "Buy milk" };
await todo.Save();
// Retrieve by ID
var loaded = await Todo.Get(id);
// Query all
var allTodos = await Todo.All();
// Filter with LINQ
var completed = await Todo.Query(t => t.Completed);
// Remove
await todo.Remove();
```
### Custom Keys (When Needed)
```csharp
// For non-GUID keys: Entity<T, TKey>
public class NumericEntity : Entity<NumericEntity, int>
{
public override int Id { get; set; }
public string Title { get; set; } = "";
}
// Manual key management
var entity = new NumericEntity { Id = 42, Title = "Meaningful" };
await entity.Save();
```
## Batch Operations
### Batch Retrieval (Prevents N+1 Queries)
```csharp
// ✅ EFFICIENT: Single bulk query with IN clause
var ids = new[] { id1, id2, id3, id4 };
var todos = await Todo.Get(ids, ct);
// Result: [Todo?, Todo?, null, Todo?] - preserves order, null for missing
// ❌ INEFFICIENT: N database round-trips
var todos = new List<Todo?>();
foreach (var id in ids)
{
todos.Add(await Todo.Get(id, ct)); // N queries!
}
```
**Use Cases:**
- Collection/playlist pagination - fetch page of items by stored IDs
- Relationship navigation - fetch all related entities at once
- Bulk validation - check which IDs exist in single query
**Performance:** Single query vs N queries = 10-100x faster for typical datasets
### Batch Persistence
```csharp
// Bulk save - efficient provider-specific batching
var todos = Enumerable.Range(0, 1000)
.Select(i => new Todo { Title = $"Task {i}" })
.ToList();
await todos.Save();
// Batch operations - add/update/delete in one transaction
await Todo.Batch()
.Add(new Todo { Title = "New task" })
.Update(existingId, todo => todo.Completed = true)
.Delete(oldId)
.SaveAsync();
```
## Pagination & Streaming
### Pagination (Web APIs)
```csharp
// Basic pagination
var page = await Todo.Page(pageNumber: 1, pageSize: 20);
// With total count for UI
var result = await Todo.QueryWithCount(
t => t.ProjectId == projectId,
new DataQueryOptions(
orderBy: nameof(Todo.Created),
descending: true
),
ct);
Console.WriteLine($"Showing {result.Items.Count} of {result.TotalCount}");
```
### Streaming (Large Datasets)
```csharp
// Stream to avoid loading everything into memory
await foreach (var todo in Todo.AllStream(batchSize: 1000, ct))
{
// Process in batches - memory-efficient
await ProcessTodo(todo);
}
// Stream with filter
await foreach (var reading in Reading.QueryStream(
"plot == 'A1'",
batchSize: 200,
ct))
{
await ProcessReading(reading);
}
```
**When to Stream:** Large datasets (>10k records), background jobs, ETL pipelines
## Anti-Patterns to Avoid
### ❌ WRONG: Manual Repository Pattern
```csharp
// DON'T create repository interfaces
public interface ITodoRepository
{
Task<Todo> GetAsync(string id);
Task SaveAsync(Todo todo);
Task<List<Todo>> GetAllAsync();
}
// DON'T inject repositories
public class TodoService
{
private readonly ITodoRepository _repo; // Unnecessary!
public TodoService(ITodoRepository repo) => _repo = repo;
}
```
**Why wrong?** Entity<T> already provides all repository functionality. Manual repositories:
- Duplicate framework features
- Break provider transparency
- Add unnecessary abstraction layers
- Increase maintenance burden
### ✅ CORRECT: Entity Service Pattern
```csharp
// Business logic services use Entity<T> directly
public class TodoService
{
public async Task<Todo> CompleteAsync(string id)
{
var todo = await Todo.Get(id); // Direct entity usage
if (todo is null)
throw new InvalidOperationException("Todo not found");
todo.Completed = true;
return await todo.Save(); // Instance save method
}
public async Task<List<Todo>> GetCompletedAsync()
{
return await Todo.Query(t => t.Completed); // Static query
}
}
```
## When This Skill Applies
Invoke this skill when:
- ✅ Creating new entities
- ✅ Adding data access code
- ✅ Refactoring repositories to Entity<T>
- ✅ Building CRUD operations
- ✅ Reviewing data access patterns
- ✅ Troubleshooting entity persistence
- ✅ Optimizing queries (batch operations, streaming)
## Advanced: Count Operations
```csharp
// Default: framework chooses best strategy (usually optimized)
var total = await Todo.Count;
// Explicit exact count (guaranteed accuracy, may be slower)
var exact = await Todo.Count.Exact(ct);
// Explicit fast count (metadata estimate, extremely fast)
var fast = await Todo.Count.Fast(ct);
// Filtered count
var completed = await Todo.Count.Where(t => t.Completed);
```
**Performance:** Fast counts use database metadata (1000-20000x faster on large tables)
- Postgres: `pg_stat_user_tables` (~5ms vs 25s for 10M rows)
- SQL Server: `sys.dm_db_partition_stats` (~1ms vs 20s)
- MongoDB: `estimatedDocumentCount()` (~10ms vs 15s)
**When to Use:**
- **Fast**: Pagination UI, dashboard summaries, estimates acceptable
- **Exact**: Critical business logic, inventory counts, reports requiring accuracy
## Bundled Resources
- `examples/entity-crud.cs` - Complete CRUD patterns
- `examples/entity-relationships.cs` - Navigation helpers
- `examples/batch-operations.cs` - Bulk loading and saving
- `anti-patterns/manual-repositories.md` - What NOT to do with detailed explanations
## Reference Documentation
- **Full Guide:** `docs/guides/entity-capabilities-howto.md`
- **Data Modeling:** `docs/guides/data-modeling.md`
- **ADR:** DATA-0059 (Entity-first facade decision)
- **Sample:** `samples/S1.Web/` (Relationship patterns)
- **Sample:** `samples/S0.ConsoleJsonRepo/` (Minimal 20-line example)
## Framework Compliance
Entity<T> patterns are **mandatory** in Koan Framework. Manual repositories break:
- Provider transparency
- Framework auto-registration
- Capability detection
- Multi-tenant context routing
Always prefer Entity<T> patterns over custom data access abstractions.Related Skills
brand-identity
Provides the single source of truth for brand guidelines, design tokens, technology choices, and voice/tone. Use this skill whenever generating UI components, styling applications, writing copy, or creating user-facing assets to ensure brand consistency.
azure-identity-ts
Authenticate to Azure services using Azure Identity SDK for JavaScript (@azure/identity). Use when configuring authentication with DefaultAzureCredential, managed identity, service principals, or i...
azure-identity-java
Azure Identity Java SDK for authentication with Azure services. Use when implementing DefaultAzureCredential, managed identity, service principal, or any Azure authentication pattern in Java applic...
abp-entity-patterns
ABP Framework domain layer patterns including entities, aggregates, repositories, domain services, and data seeding. Use when: (1) creating entities with proper base classes, (2) implementing custom repositories, (3) writing domain services, (4) seeding data.
mobile-first-design-rules
Focuses on rules and best practices for mobile-first design and responsive typography using tailwind.
entity-class-conventions
Sets the standards for entity class design including annotations, ID generation strategies, and relationship configurations for database interaction.
Enforce Agent Identity in Skill
No description provided.
agent-identity
Cryptographic identity for AI agents. Register on-chain identity, sign messages, verify other agents, link platform accounts. Stake USDC to prove you're real. Built by g1itchbot for the USDC Hackathon.
alignfirst
Collaborative problem-solving protocols: write technical specifications (spec, or alspec), create implementation plans (plan, or alplan), or use Align-and-Do Protocol (AAD). Also generates PR/MR descriptions (aldescription).
koan-api-building
EntityController<T>, custom routes, payload transformers, auth policies
api-first-design
**API FIRST DESIGN**: 'API 만들어', 'API 설계', '엔드포인트', 'REST', 'Swagger', 'OpenAPI', 'DTO', 'CRUD' 요청 시 자동 발동. *.controller.ts/*.dto.ts/routes/** 파일 작업 시 자동 적용. Contract-First, 표준 응답 포맷, 타입 자동 생성.
koan-ai-integration
Chat endpoints, embeddings, RAG workflows, vector search