# Licensing — `[RequiresLicense]` attribute (v3.46+)

> Extracted from `smartstack-api.md` for clarity. Loaded only when generating code that needs license gating.

Mark a Command or Query as requiring a valid license / feature / write capability.

## Attribute definition

```csharp
namespace SmartStack.Application.Common.Licensing;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class RequiresLicenseAttribute : Attribute
{
    public string? Feature { get; }
    public bool IsWriteOperation { get; }

    public RequiresLicenseAttribute() { /* just needs valid license */ }
    public RequiresLicenseAttribute(bool isWriteOperation) { /* blocked in read-only mode */ }
    public RequiresLicenseAttribute(string feature, bool isWriteOperation = false) { /* both */ }
}
```

## Usage on a Command

```csharp
[RequiresLicense(LicenseFeatures.AdvancedWorkflows, isWriteOperation: true)]
public record CreateAdvancedWorkflowCommand(string Name, ...) : IRequest<WorkflowDto>;
```

## Behavior at runtime

- A MediatR pipeline behavior reads the attribute on the request type.
- `Feature` → checked against the cached `License.Features` (resolved per-tenant from JWT).
- `IsWriteOperation = true` → blocked when the system is in read-only mode (license expired but in grace period, license downgraded, …).
- Failures throw a typed exception → 403 Forbidden with a stable error code (`LICENSE_FEATURE_DISABLED`, `LICENSE_READ_ONLY`).

## Where to read feature constants

`SmartStack.Domain.Licensing.LicenseFeatures` (string consts — `Entra`, `AdvancedWorkflows`, `AiAdvanced`, …).

## DO / DON'T

- DO put `[RequiresLicense]` on the request (Command/Query), not on the handler
- DO use `LicenseFeatures.X` constants — never magic strings
- DON'T add `[RequiresLicense]` on `[AllowAnonymous]` endpoints — they bypass the pipeline
- DON'T duplicate the check in the handler body — the pipeline already enforced it

## Sources

- `D:/01 - projets/SmartStack.app/features/IA-Workflow/src/SmartStack.Application/Common/Licensing/RequiresLicenseAttribute.cs`
- `D:/01 - projets/SmartStack.app/features/IA-Workflow/src/SmartStack.Domain/Licensing/LicenseFeatures.cs`
