npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@remade/nestjs-approvals

v0.1.0

Published

PR-style approval workflow system for NestJS with TypeORM

Readme

@app/approvals

A domain-agnostic, PR-style approval system for NestJS applications. Attaches structured approval workflows to any entity via an opaque externalRefId. Supports parallel and sequential review stages, blocking comment threads, cancellation, and a full audit trail. Ships as a NestJS dynamic module backed by TypeORM on PostgreSQL.


Quick Start

ApprovalsModule.forRoot({
  controllers: { enabled: true },
  connectionName: 'default',
})

Set controllers.enabled to false to register only services and engine without exposing REST endpoints.

Documentation

| Document | Description | |---|---| | Overview & Architecture | Quick start, module options, architecture, design decisions, exports | | Lifecycle & Engine | State machine, transitions, PolicyResolver, BlockingThreadChecker | | Entities | All 6 entities with fields, relationships, and constraints | | Approval Policy | Policy configuration, resolution algorithm, defaults | | Workflow Modes | Parallel, sequential, blocking threads | | API Reference | REST endpoints, DTOs, service methods | | Events | Domain events, enums, event string keys |

Directory Structure

libs/approvals/src/
├── approvals.module.ts          # Dynamic module (forRoot / forRootAsync)
├── approvals.constants.ts       # Injection tokens
├── index.ts                     # Barrel export
├── config/                      # Default approval policy
├── interfaces/                  # Module options, ApprovalPolicy type
├── enums/                       # 6 enums (status, roles, decisions, etc.)
├── entities/                    # 6 TypeORM entities
├── engine/                      # StateMachine, PolicyResolver, BlockingThreadChecker
├── events/                      # 20 domain event classes
├── dto/                         # Request DTOs with class-validator
├── services/                    # 5 services
└── controllers/                 # 5 REST controllers

Entities

| Entity | Table | Purpose | |---|---|---| | ApprovalRequest | approvals_requests | Central workflow record with denormalized policy | | Reviewer | approvals_reviewers | Reviewer assignment with role, state, and stage | | Review | approvals_reviews | Immutable decision record | | CommentThread | approvals_comment_threads | Threaded discussion, optionally blocking | | Comment | approvals_comments | Individual comment with soft-delete | | AuditEntry | approvals_audit_entries | Immutable action log |

API Endpoints

All routes are prefixed with approval-requests.

| Method | Path | Description | |---|---|---| | POST | /approval-requests | Create request | | GET | /approval-requests | List requests | | GET | /approval-requests/:id | Get request by ID | | PATCH | /approval-requests/:id | Update request | | POST | /approval-requests/:id/submit | Submit for review | | POST | /approval-requests/:id/close | Close | | POST | /approval-requests/:id/reopen | Reopen | | POST | /approval-requests/:id/cancel | Cancel (creator only) | | POST | /approval-requests/:id/reviewers | Add reviewer | | DELETE | /approval-requests/:id/reviewers/:userId | Remove reviewer | | GET | /approval-requests/:id/reviewers | List reviewers | | POST | /approval-requests/:id/reviews | Submit review | | GET | /approval-requests/:id/reviews | List reviews | | POST | /approval-requests/:id/reviews/:reviewId/dismiss | Dismiss review | | POST | /approval-requests/:id/threads | Create thread | | GET | /approval-requests/:id/threads | List threads | | POST | /approval-requests/:id/threads/:threadId/comments | Reply | | PATCH | /approval-requests/:id/threads/:threadId/comments/:commentId | Edit comment | | DELETE | /approval-requests/:id/threads/:threadId/comments/:commentId | Delete comment | | POST | /approval-requests/:id/threads/:threadId/resolve | Resolve thread | | POST | /approval-requests/:id/threads/:threadId/unresolve | Unresolve thread | | GET | /approval-requests/:id/audit | Audit trail |

Exported Services

| Service | Purpose | |---|---| | ApprovalRequestService | CRUD, submit, close, reopen, cancel | | ReviewerService | Add/remove reviewers, policy re-evaluation | | ReviewService | Submit/dismiss reviews, stage advancement | | CommentService | Threads, replies, resolve/unresolve | | AuditService | Immutable action logging |

Key Design Decisions

  1. Policy denormalization -- JSONB policy frozen at request creation; in-flight workflows are immune to changes.
  2. Pure engine -- StateMachine and PolicyResolver are DB-free and deterministic.
  3. Optimistic locking -- @VersionColumn() on ApprovalRequest prevents concurrent write conflicts.
  4. Transactional writes -- All mutations use DataSource.transaction() with audit entries in the same transaction.
  5. Reviewer-centric stages -- No separate stage entity; stages are a reviewer property.
  6. Blocking threads -- Boolean flag on comment threads reuses thread/resolve infrastructure.