<p align="center">
<svg width="680" height="120" viewBox="0 0 680 120" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="@xemahq/xema-decorators">
  <rect width="680" height="120" rx="14" fill="#0B1020"/>
  <g transform="translate(28,34)">
    <path d="M26 0 L52 15 L52 45 L26 60 L0 45 L0 15 Z" fill="#8B5CF6" opacity="0.18"/>
    <path d="M26 12 L41 21 L41 39 L26 48 L11 39 L11 21 Z" fill="#8B5CF6"/>
  </g>
  <text x="92" y="52" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="22" fill="#F8FAFC" font-weight="700">@xemahq/xema-decorators</text>
  <text x="92" y="80" font-family="ui-sans-serif,system-ui,sans-serif" font-size="15" fill="#94A3B8">Declarative NestJS decorators for routes and capabilities.</text>
  <text x="652" y="105" text-anchor="end" font-family="ui-sans-serif,system-ui,sans-serif" font-size="12" fill="#475569">xema.dev</text>
</svg>
</p>

<p align="center">
  <a href="https://xema.dev">Website</a> &middot;
  <a href="https://www.npmjs.com/package/@xemahq/xema-decorators">npm</a>
</p>

<p align="center">
  <img alt="npm" src="https://img.shields.io/npm/v/%40xemahq%2Fxema-decorators?color=2563eb&label=npm">
  <img alt="license" src="https://img.shields.io/npm/l/%40xemahq%2Fxema-decorators?color=10b981">
  <img alt="types" src="https://img.shields.io/npm/types/%40xemahq%2Fxema-decorators?color=3178c6">
</p>

# @xemahq/xema-decorators

> Declarative NestJS decorators for routes and capabilities.

## Overview

The annotation layer that lets a service declare its routes, resources, and
capabilities directly on its controllers. Decorators like `@XemaResource`,
`@XemaRoute`, `@XemaPublicRoute`, and `@XemaCapability` mark intent; a
convention-inference engine derives actions, operation ids, and
the resolved space from naming conventions. At boot, `XemaRuntimeModule` scans
the application and emits the route, capability, and service manifests — so
those manifests are generated from the code rather than hand-maintained.

## When to use it

- Use it to declare a NestJS service's route and capability surface as
  annotations instead of separate hand-written manifests.
- Reach for the inference engine standalone in tests or codemods that need to
  derive actions or permissions from route metadata.
- Declare a browser-facing composition (BFF) surface with `@BffController`,
  which carries the whole contract in one decorator: a public API surface, a
  user-token-only fence, a stated org-role floor with both guards mounted, and
  an enforced `bff/` mount prefix.

## Installation

```bash
pnpm add @xemahq/xema-decorators
```

## Usage

```ts
import { XemaResource, XemaRoute, XemaPublicRoute } from '@xemahq/xema-decorators';

@XemaResource('invoice')
@Controller('invoices')
export class InvoiceController {
  @XemaPublicRoute()
  @Get()
  list() { /* ... */ }

  @XemaRoute()
  @Post()
  create() { /* ... */ }
}
```

A browser-facing composition surface declares its whole contract at once. The
org-role floor is required rather than defaulted — an omitted tier on an
administrative surface is a failure, not a default — and the mount path must
begin with `bff/`, which is checked when the class is declared.

```ts
import { OrgRole } from '@xemahq/platform-common';
import { BffController } from '@xemahq/xema-decorators';

@BffController({ resource: 'invoice', path: 'bff/invoices', orgRole: OrgRole.Member })
export class InvoiceBffController {
  @Get()
  summary() { /* ... */ }
}
```

## Peer requirements

- `@nestjs/common`, `@nestjs/core` — host framework.
- `@xemahq/platform-common` — request context, token classes and org roles;
  `@BffController` composes its guards.
- `reflect-metadata` — decorator metadata runtime.

## License

Apache-2.0 &copy; Xema — [xema.dev](https://xema.dev)
