Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Enforce LF line endings for all text files on all platforms
* text=auto eol=lf

# Explicitly declare binary files to prevent corruption
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.woff binary
*.woff2 binary
*.ttf binary
*.otf binary
*.eot binary
11 changes: 8 additions & 3 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ permissions:

jobs:
validate:
name: CI - PR Validation
runs-on: ubuntu-latest
name: CI - PR Validation (Node ${{ matrix.node-version }} / ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [20, 22]

steps:
- name: Checkout
Expand All @@ -19,7 +24,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
node-version: ${{ matrix.node-version }}
cache: npm

- name: Install
Expand Down
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"printWidth": 100
"printWidth": 100,
"endOfLine": "lf"
}
163 changes: 140 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,148 @@
# NestJS DeveloperKit (Template)
# @ciscode/audit-kit

Template repository for building reusable NestJS npm packages.
AuditKit is a reusable NestJS module for immutable audit logging with clean architecture (`core` / `infra` / `nest`).

## What you get
It provides:

- ESM + CJS + Types build (tsup)
- Jest testing
- ESLint + Prettier
- Changesets (Release PR flow)
- Husky (pre-commit + pre-push)
- Enforced package architecture (core / infra / nest) with strict public API
- Framework-free core service (`AuditService`)
- Pluggable repositories (MongoDB, in-memory)
- Automatic change detection
- Configurable redaction, idempotency, and retention policies
- Cursor-based pagination for stable listing
- Observability hooks (OpenTelemetry-friendly observer port)
- Event streaming hooks (publisher port + default EventEmitter adapter)

## Scripts
## Install

- `npm run build` – build to `dist/`
- `npm test` – run tests
- `npm run typecheck` – TypeScript typecheck
- `npm run lint` – ESLint
- `npm run format` / `npm run format:write` – Prettier
- `npx changeset` – create a changeset
```bash
npm install @ciscode/audit-kit
```

## Release flow (summary)
Peer dependencies are managed by consuming applications.

- Work on a `feature` branch from `develop`
- Merge to `develop`
- Add a changeset for user-facing changes: `npx changeset`
- Automation opens “Version Packages” PR into `master`
- Merge to `master`, tag `vX.Y.Z` to publish
## Quick Start

See `docs/RELEASE.md` for details.
```typescript
import { Module } from "@nestjs/common";
import { AuditKitModule } from "@ciscode/audit-kit";

@Module({
imports: [
AuditKitModule.register({
repository: {
type: "in-memory",
},
redaction: {
enabled: true,
fields: ["actor.email", "metadata.password"],
mask: "[REDACTED]",
},
idempotency: {
enabled: true,
keyStrategy: "idempotencyKey",
},
}),
],
})
export class AppModule {}
```

## Usage

```typescript
import { Injectable } from "@nestjs/common";
import { ActorType, AuditActionType, AuditService } from "@ciscode/audit-kit";

@Injectable()
export class UserService {
constructor(private readonly auditService: AuditService) {}

async updateUser(): Promise<void> {
await this.auditService.log({
actor: { id: "user-1", type: ActorType.USER, email: "user@example.com" },
action: AuditActionType.UPDATE,
resource: { type: "user", id: "user-1" },
metadata: { reason: "profile update" },
idempotencyKey: "req-123",
});
}
}
```

## Advanced Features

### Cursor Pagination

```typescript
const page1 = await auditService.queryWithCursor({ actorId: "user-1" }, { limit: 20 });

if (page1.hasMore) {
const page2 = await auditService.queryWithCursor(
{ actorId: "user-1" },
{ limit: 20, cursor: page1.nextCursor },
);
}
```

### Observability Hooks

Provide an observer to emit metrics/spans/log events (for OpenTelemetry, Prometheus, etc.):

```typescript
AuditKitModule.register({
repository: { type: "in-memory" },
observer: {
onEvent(event) {
// event.operation, event.durationMs, event.success
console.log(event);
},
},
});
```

### Event Streaming

Emit domain events after successful audit creation:

```typescript
AuditKitModule.register({
repository: { type: "in-memory" },
eventStreaming: {
enabled: true,
// optional custom publisher; default is EventEmitter adapter
publisher: {
publish(event) {
console.log(event.type, event.payload.id);
},
},
},
});
```

## Tooling

- Tests: `npm test`
- Typecheck: `npm run typecheck`
- Lint: `npm run lint`
- Build: `npm run build`
- Mutation testing: `npm run mutation`
- Benchmarks: `npm run bench`

## CI Compatibility Matrix

PR validation runs on a matrix to catch environment regressions early:

- Node.js: 20, 22
- OS: ubuntu-latest, windows-latest

See [.github/workflows/pr-validation.yml](.github/workflows/pr-validation.yml).

## Release Flow (Summary)

1. Work on a feature branch from `develop`
2. Add a changeset for user-facing changes: `npx changeset`
3. Merge into `develop`
4. Automation opens "Version Packages" PR into `master`
5. Merge and publish

See [docs/RELEASE.md](docs/RELEASE.md) for details.
Loading
Loading