Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Add Use Case

ASecurity

Build a complete vertical slice in Protean - the full command flow from command definition through handler, aggregate mutation, event raising, and event handler reaction. This is the most common workflow for adding a new feature. Use when the user asks to "add a use case", "add a feature", "create a command flow", "implement a vertical slice", "add a new action", "build an end-to-end flow", "add command processing", or when they describe actions like "users should be able to place orders", "a...

45 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentpythongoreactapi

Works with

api

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add proteanhq/protean --skill add-use-case --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Use Case?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Add Use Case
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/proteanhq-add-use-case/badge)](https://www.skillsdirectory.com/skills/proteanhq-add-use-case)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: add-use-case
description: Build a complete vertical slice in Protean - the full command flow from command definition through handler, aggregate mutation, event raising, and event handler reaction. This is the most common workflow for adding a new feature. Use when the user asks to "add a use case", "add a feature", "create a command flow", "implement a vertical slice", "add a new action", "build an end-to-end flow", "add command processing", or when they describe actions like "users should be able to place orders", "allow admins to approve requests", "implement the checkout flow".
license: Apache-2.0
compatibility: Requires Python 3.11+, protean framework
metadata:
  author: proteanhq
  version: "0.1"
  category: workflow
  composes: [command, command-handler, aggregate, event, event-handler]
---

# Add Use Case

A use case in Protean follows the command flow pattern. Each use case is a vertical slice through the architecture:

```
Command → Command Handler → Aggregate Method → Event → Event Handler
```

## What this creates

| Component | Purpose | Decorator |
|-----------|---------|-----------|
| Command | Carries user intent and input data | `@domain.command(part_of=...)` |
| Command Handler | Receives command, orchestrates aggregate | `@domain.command_handler(part_of=...)` |
| Aggregate method | Mutates state, raises events | Method on `@domain.aggregate` |
| Event | Records what happened | `@domain.event(part_of=...)` |
| Event Handler | Reacts to what happened (side effects) | `@domain.event_handler(part_of=...)` |

## Information to gather

Before building a use case, understand:

- [ ] **What action does the user take?** — Name it as an imperative verb phrase (e.g., "Place Order", "Approve Request")
- [ ] **What data is required?** — Command fields (input from user/API)
- [ ] **Which aggregate does it modify?** — The aggregate that owns the business logic
- [ ] **What state change occurs?** — The mutation in the aggregate method
- [ ] **What happened after?** — The event to raise (past tense: "OrderPlaced", "RequestApproved")
- [ ] **What side effects follow?** — Event handler reactions (notifications, syncing, downstream updates)

## Process

### Step 1: Define the command

Commands are named as imperative verb phrases. They carry the data needed to perform the action. Use `part_of` to associate with the target aggregate.

```python
@domain.command(part_of="Order")
class PlaceOrder:
    order_id: Identifier(required=True)
    customer_id: Identifier(required=True)
    product_id: Identifier(required=True)
    quantity: Integer(required=True, min_value=1)
```

**Key rules for commands** (see [command](../command/SKILL.md)):
- Named as imperative: `PlaceOrder`, `ApproveRequest`, `CancelSubscription`
- Fields are the input data, not the entire aggregate state
- `required=True` on mandatory fields — raises `InvalidDataError` if missing
- Use field constraints for basic validation (Layer 1)

### Step 2: Define the event

Events record what happened after the command was processed. Named in past tense.

```python
@domain.event(part_of="Order")
class OrderPlaced:
    order_id: Identifier(required=True)
    customer_id: Identifier(required=True)
    product_id: Identifier(required=True)
    quantity: Integer(required=True)
    total_amount: Float(required=True)
```

### Step 3: Add the aggregate method

The aggregate method encapsulates the business logic. It mutates state and raises the event.

```python
@domain.aggregate
class Order:
    customer_id: Identifier(required=True)
    product_id: Identifier(required=True)
    quantity: Integer(required=True)
    total_amount: Float(default=0.0)
    status: String(default="placed")

    @classmethod
    def place(cls, customer_id, product_id, quantity, unit_price):
        """Factory method for placing a new order."""
        total = quantity * unit_price
        order = cls(
            customer_id=customer_id,
            product_id=product_id,
            quantity=quantity,
            total_amount=total,
        )
        order.raise_(OrderPlaced(
            order_id=order.id,
            customer_id=customer_id,
            product_id=product_id,
            quantity=quantity,
            total_amount=total,
        ))
        return order
```

### Step 4: Build the command handler

The command handler receives the command, orchestrates the aggregate, and persists it. Use `domain.process(command, asynchronous=False)` for synchronous processing.

```python
@domain.command_handler(part_of=Order)
class OrderCommandHandler:
    @handle(PlaceOrder)
    def handle_place_order(self, command: PlaceOrder):
        order = Order.place(
            customer_id=command.customer_id,
            product_id=command.product_id,
            quantity=command.quantity,
            unit_price=10.0,  # In real code, look up from catalog
        )
        domain.repository_for(Order).add(order)
```

**Key rules for command handlers** (see [command-handler](../command-handler/SKILL.md)):
- `part_of=AggregateClass` (command handlers require the class reference — a string `part_of` raises at registration)
- Use `@handle(CommandClass)` decorator on each handler method
- Each handler method has signature `(self, command: CommandClass)`
- Implicit UnitOfWork — no manual transaction management needed
- Load aggregate → call method → persist via `repository_for().add()`

### Step 5: Add the event handler (optional)

Event handlers react to events for side effects: notifications, cross-aggregate updates, logging.

```python
@domain.event_handler(part_of=Notification, stream_category=Order.meta_.stream_category)
class OrderNotificationHandler:
    @handle(OrderPlaced)
    def on_order_placed(self, event: OrderPlaced):
        notification = Notification(
            message=f"Order {event.order_id} placed for customer {event.customer_id}"
        )
        domain.repository_for(Notification).add(notification)
```

### Step 6: Process the command

```python
domain.process(
    PlaceOrder(
        order_id="ORD-001",
        customer_id="CUST-001",
        product_id="PROD-001",
        quantity=3,
    ),
    asynchronous=False,
)
```

## The command flow

```
1. API/UI creates Command with input data
2. domain.process(command) dispatches to Command Handler
3. Command Handler loads/creates Aggregate
4. Aggregate method mutates state and raises Event
5. Handler persists Aggregate (with events) via repository
6. Event is published to event store
7. Event Handler(s) pick up the event and react
```

## Use case patterns

### Create pattern (factory method)

```python
# Handler creates a new aggregate
@handle(PlaceOrder)
def handle(self, command):
    order = Order.place(...)  # Factory method
    domain.repository_for(Order).add(order)
```

### Update pattern (load and mutate)

```python
# Handler loads existing aggregate and calls method
@handle(ApproveOrder)
def handle(self, command):
    order = domain.repository_for(Order).get(command.order_id)
    order.approve(approved_by=command.approver_id)
    domain.repository_for(Order).add(order)
```

### Guard pattern (validation before action)

```python
# Handler validates context before aggregate operation
@handle(CancelOrder)
def handle(self, command):
    if command.requested_by_role not in ["admin", "customer"]:
        raise ValidationError({"authorization": ["Not authorized"]})
    order = domain.repository_for(Order).get(command.order_id)
    order.cancel(reason=command.reason)
    domain.repository_for(Order).add(order)
```

## Naming conventions

| Component | Convention | Example |
|-----------|-----------|---------|
| Command | Imperative verb phrase | `PlaceOrder`, `ApproveRequest` |
| Event | Past tense of command | `OrderPlaced`, `RequestApproved` |
| Handler class | `{Aggregate}CommandHandler` | `OrderCommandHandler` |
| Handler method | `handle_{command}` | `handle_place_order` |
| Aggregate factory | `cls.{verb}(...)` | `Order.place(...)` |
| Aggregate method | `self.{verb}(...)` | `order.approve(...)` |
| Event handler class | Descriptive name | `OrderNotificationHandler` |

## Common mistakes

### Business logic in the handler instead of the aggregate

```python
# Wrong! Business rule computed in the handler
@handle(PlaceOrder)
def handle(self, command):
    order = Order(customer_id=command.customer_id)
    order.total_amount = command.quantity * 10.0  # rule leaks into the handler
    order.status = "placed"
    domain.repository_for(Order).add(order)
```

Instead: keep the rule in an aggregate method/factory; the handler only orchestrates.

```python
@handle(PlaceOrder)
def handle(self, command):
    order = Order.place(customer_id=command.customer_id, quantity=command.quantity, unit_price=10.0)
    domain.repository_for(Order).add(order)
```

### Forgetting to raise the event

```python
# Wrong! State changes, but nothing is recorded or published
@classmethod
def place(cls, **kwargs):
    order = cls(**kwargs)
    return order  # no raise_()
```

Instead: raise the past-tense event so the fact is recorded and handlers can react: `order.raise_(OrderPlaced(...))`.

### Persisting multiple aggregates in one handler

```python
# Wrong! Two aggregates mutated and saved in one transaction
@handle(PlaceOrder)
def handle(self, command):
    order = Order.place(...)
    inventory.reduce(command.quantity)
    domain.repository_for(Order).add(order)
    domain.repository_for(Inventory).add(inventory)  # cross-aggregate write
```

Instead: persist one aggregate and coordinate the other via an event handler (eventual consistency); for an atomic cross-aggregate rule use a domain service.

### Authorization inside the aggregate

```python
# Wrong! Context/authorization baked into the domain model
def cancel(self, role):
    if role != "admin":
        raise ValidationError({"authorization": ["Not authorized"]})
```

Instead: guard authorization in the handler (Layer 4); keep the aggregate focused on invariants.

## Complete examples

- [Basic use case](assets/use_case_basic.py) — Command → Handler → Aggregate → Event (create pattern)
- [Use case with update](assets/use_case_with_update.py) — Load, mutate, and persist (update pattern with event handler)
- [Use case with guards](assets/use_case_with_guards.py) — Authorization guard + existence check in handler

## Detailed references

- [Vertical Slice Architecture](references/vertical-slice.md) — How command flow implements vertical slices
- [Command Flow Patterns](references/command-flow-patterns.md) — Create, update, and guard patterns

## Related skills

- [command](../command/SKILL.md) — Command definition and field validation
- [command-handler](../command-handler/SKILL.md) — Handler patterns
- [aggregate](../aggregate/SKILL.md) — Aggregate methods and event raising
- [event](../event/SKILL.md) — Event definition
- [event-handler](../event-handler/SKILL.md) — Event handler patterns
- [add-validation](../add-validation/SKILL.md) — Adding validation at each layer

Attribution

proteanhqproteanhq
View sourceMore from proteanhq →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →