---
name: feature-full
description: |
  Creates a complete SmartStack feature with all integrations.
  Use this skill when:
  - User wants to create a complete feature from A to Z
  - User mentions "oneshot", "complete feature", "full-stack"
  - Creating a module with notifications, workflows and/or AI
  - Need for complete user experience
  Scope: Domain → Application → Infrastructure → API → Web + Notifications + Workflows + AI
disable-model-invocation: true
---

# Skill Feature Full SmartStack

> **OneShot Development:** Orchestrates all skills for a complete feature.

**Reference:** [_shared.md](../_shared.md) for architecture, permissions, i18n

## WHEN THIS SKILL ACTIVATES

| Trigger | Example |
|---------|---------|
| Complete feature | "Create a product management module" |
| Full-stack | "Create the backend and frontend for..." |
| Integration | "With notifications and automated emails" |

## COMPLETE FLOW

```
DOMAIN → APPLICATION → INFRASTRUCTURE → API → WEB
                      + NOTIFICATIONS + WORKFLOWS + AI
```

## CREATION WORKFLOW

### PHASE 1: ANALYSIS

```
□ Module/functionality?
□ Entities? CRUD operations? Business rules?
□ Notifications required? Automated emails? AI?
□ Display: Cards/Table/Kanban? Permissions?
```

### PHASE 2: DOMAIN

```csharp
// {Entity}.cs - Factory Method + Behaviors
public class {Entity} : BaseEntity, IAuditableEntity
{
    public string Name { get; private set; }
    public {Entity}Status Status { get; private set; }
    private {Entity}() { }
    public static {Entity} Create(string name, Guid createdById) =>
        new { Id = Guid.NewGuid(), Name = name, Status = {Entity}Status.Active, ... };
    public void Update(string name) => Name = name ?? throw new DomainException("Name required");
}

// {Entity}Status.cs
public enum {Entity}Status { Active = 0, Inactive = 1, Archived = 2 }
```

### PHASE 3: APPLICATION

```csharp
// I{Entity}Service.cs
Task<PagedResult<{Entity}Dto>> GetAllAsync(...);
Task<{Entity}Dto> CreateAsync(Create{Entity}Request request, CancellationToken ct);

// DTOs
public record {Entity}Dto(Guid Id, string Name, string Status, DateTime CreatedAt);
public record Create{Entity}Request(string Name, string? Description);

// Permissions.cs + PermissionConfiguration.cs (2 files!)
public const string View = "{context}.{area}.{module}.read";
```

### PHASE 4: INFRASTRUCTURE

```csharp
// {Entity}Configuration.cs
builder.ToTable("{Entity}s", "{schema}");
builder.Property(x => x.Name).HasMaxLength(200).IsRequired();

// {Entity}Service.cs with Notifications
public async Task<{Entity}Dto> CreateAsync(...) {
    var entity = {Entity}.Create(request.Name, _currentUser.Id);
    _context.{Entity}s.Add(entity);
    await _context.SaveChangesAsync(ct);
    await _notificationService.SendNotificationAsync(_currentUser.Id,
        NotificationType.{Entity}Created, "Created", $"{entity.Name} created",
        relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, ct);
    return MapToDto(entity);
}

// DependencyInjection.cs
services.AddScoped<I{Entity}Service, {Entity}Service>();
```

### PHASE 5: API

```csharp
[ApiController][Route("api/{area}/{module}")][Authorize]
public class {Entity}Controller : ControllerBase
{
    [HttpGet][RequirePermission(Permissions.{Area}.{Module}.View)]
    [ProducesResponseType(typeof(PagedResult<{Entity}Dto>), 200)]
    public async Task<ActionResult<PagedResult<{Entity}Dto>>> GetAll(...);

    [HttpPost][RequirePermission(Permissions.{Area}.{Module}.Create)]
    [ProducesResponseType(typeof({Entity}Dto), 201)]
    public async Task<ActionResult<{Entity}Dto>> Create([FromBody] request, CancellationToken ct);
}
```

### PHASE 6: FRONTEND

```typescript
// {module}Api.ts
export const {module}Api = {
  getAll: (page, pageSize, search?) => apiClient.get<PagedResult<{Entity}Dto>>('/{area}/{module}', { params }),
  create: (data) => apiClient.post<{Entity}Dto>('/{area}/{module}', data),
};

// use{Module}.ts with SignalR
export function use{Module}() {
  const queryClient = useQueryClient();
  useSignalR({ onNotification: (n) => {
    if (n.relatedEntityType === '{Entity}') queryClient.invalidateQueries(['{module}']);
  }});
  const createMutation = useMutation({ mutationFn: {module}Api.create, onSuccess: () => ... });
  return { create: createMutation.mutate, ... };
}

// {Module}Page.tsx with EntityCard
<EntityCard title={item.name} actions={[{ label: 'View', onClick: () => navigate(...) }]} />

// Routes (nested mandatory)
<Route path="{area}"><Route path="{module}"><Route index element={<{Module}Page />} /></Route></Route>
```

### PHASE 7: INTEGRATIONS

#### Notifications
```csharp
await _notificationService.SendNotificationAsync(userId, NotificationType.{Entity}Created,
    title, message, relatedEntityType: nameof({Entity}), relatedEntityId: entity.Id, actionUrl);
```

#### Workflow Email
```csharp
// 1. WorkflowTriggerConfiguration.cs: new { Code = "{entity}.created", ... }
// 2. WorkflowConfiguration.cs: new { TriggerId = ..., ... }
// 3. Service:
await _workflowService.TriggerAsync("{entity}.created", new Dictionary<string, object>{...});
```

#### AI
```csharp
var result = await _aiCompletionService.ExecutePromptByCodeWithValidationAsync<{Entity}AnalysisResult>(
    "{entity}-analyzer", new Dictionary<string, object>{ ["name"] = entity.Name }, ct);
```

## COMPLETE CHECKLIST

### Backend
```
□ Domain: Entity + Factory + Behaviors + Enum + IAuditableEntity
□ Application: Interface + DTOs + Permissions (2 files!)
□ Infrastructure: EF Config + Service + DI + DbSet + Migration
□ API: Controller + Authorize + RequirePermission + ProducesResponseType
```

### Frontend
```
□ {module}Api.ts + use{Module}.ts (with SignalR) + {Module}Page.tsx + {Module}Form.tsx
□ i18n: fr, en, it, de
□ Nested routes in App.tsx
```

### Integrations
```
□ Notifications: NotificationType + SendNotificationAsync + useSignalR
□ Workflows: Trigger + Workflow + TriggerAsync
□ AI: Prompt + OutputSchema + ExecutePromptAsync
```

### Validation
```
□ dotnet build + npm run build + npm run lint OK
```

## ORCHESTRATED SKILLS

| Skill | Phase |
|-------|-------|
| `/application` | 2-6 |
| `/controller` | 5 |
| `/notification` | 7.1 |
| `/workflow` | 7.2 |
| `/ai-prompt` | 7.3 |
| `/ui-components` | 6 |
| `/efcore:migration` | 4 |

## ABSOLUTE RULES

| DO | DON'T |
|----|-------|
| Layered architecture | Direct frontend DB access |
| Entity Factory Methods | Hardcoded permission strings |
| Permissions 2 files | Flat routes |
| SignalR hooks | Skip i18n 4 languages |
| ProducesResponseType | Skip logging |
