pvarentsov/typescript-clean-architecture
45.7
Weak · 21 September 2026
3.7k
lines of production code
TypeScript
primary language
4
measurements over time
What this system is
This system is a NestJS-based backend application that manages media files, blog posts, and user accounts. It implements a clean architecture with a domain layer handling business logic for these three core entities, supported by a message bus for command, query, and event handling. The infrastructure layer provides persistence via TypeORM and Minio, while the API layer exposes REST endpoints with JWT authentication and Swagger documentation.
Features
Add HTTP REST authentication module with JWT and role-based access control
Introduced a new authentication module for the HTTP REST API, providing JWT-based login and role-based access control. The update adds an \HttpAuthService\ for validating users and generating access tokens, alongside \HttpJwtStrategy\ and \HttpLocalStrategy\ for handling JWT and local authentication flows. It also includes \HttpJwtAuthGuard\ and \HttpRoleAuthGuard\ to enforce authentication and authorization, supported by decorators (\HttpAuth\, \HttpRoles\, \HttpUser\) for easy integration into controllers.
src/application/api/http-rest/auth · high confidence
Add MinioMediaFileStorageAdapter for media file persistence
A new MinioMediaFileStorageAdapter has been introduced to handle media file storage operations using the Minio client. This adapter implements the MediaFileStoragePort interface, allowing the system to upload files to a Minio-compatible S3 storage backend. The implementation manages bucket selection, file metadata extraction, and storage configuration via environment variables.
src/infrastructure/adapter/persistence/media-file · high confidence
Add PostgreSQL container configuration and initialization script
A new Dockerfile and entrypoint script are added for the PostgreSQL service. The Dockerfile pulls the postgres:11.2-alpine image and copies a custom entrypoint script. The script executes on database initialization to create the uuid-ossp extension, enabling UUID generation capabilities within the database.
docker · high confidence
Add TypeORM logger adapter for NestJS integration
A new TypeOrmLogger class has been added to bridge TypeORM's logging interface with NestJS's Logger service. This implementation routes database logs, queries, errors, and schema build events through the standard NestJS logging mechanism, ensuring consistent log formatting and severity levels across the application.
src/infrastructure/adapter/persistence/typeorm/logger · high confidence
Add dependency injection tokens for media domain
A new file, MediaDITokens.ts, has been added to the media domain's dependency injection (DI) module. This file defines a MediaDITokens class that registers unique symbols for various use cases (Create, Edit, Get, Remove), query handlers (DoesMediaExist, GetMediaPreview), and repositories/storage (MediaRepository, MediaFileStorage). This establishes the DI container keys for the media domain's internal services.
src/core/domain/media/di · high confidence
Add environment configuration files for local and test environments
Added new environment variable files for local and test environments, including configurations for the API, database, and file storage services. These files define connection details, credentials, and feature flags (such as logging and access token settings) required to run the application locally or in a test environment.
env · high confidence
Add global exception filter for REST API error handling
A new global exception filter (NestHttpExceptionFilter) has been introduced to standardize how HTTP and core exceptions are transformed into a consistent API response format. The filter intercepts all unhandled exceptions, mapping Nest.js HttpException and UnauthorizedException instances to specific error codes and messages, while also supporting a custom Exception type. Additionally, the filter now respects a configuration flag (ApiServerConfig.LOG\_ENABLE) to conditionally log error details, allowing users to disable logging if desired.
src/application/api/http-rest/exception-filter · high confidence
Added Post, PostImage, and PostOwner domain entities
Introduced the core domain models for the post feature: the Post entity (with title, content, status, and timestamps), the PostImage entity (storing relative paths), and the PostOwner entity (storing user name and role). These classes implement validation via class-validator and provide factory methods for creation.
src/core/domain/post/entity · high confidence
Added PostImageRemovedEventHandler
A new event handler, PostImageRemovedEventHandler, has been added to handle MediaRemovedEvent. This interface extends EventHandler for MediaRemovedEvent, enabling the system to process media removal events within the post domain.
src/core/domain/post/handler · high confidence
Added TypeORM entity and mapper classes for Media, Post, and User domains
New TypeORM entity classes (TypeOrmMedia, TypeOrmPost, TypeOrmUser) and their corresponding mappers (TypeOrmMediaMapper, TypeOrmPostMapper, TypeOrmUserMapper) have been added to the persistence layer. These classes define the database schema for media files, posts, and users, and provide the mapping logic to convert between domain entities and ORM entities, enabling data persistence via TypeORM.
src/infrastructure/adapter/persistence/typeorm/entity · high confidence
Added TypeORM implementation for user persistence
A new TypeORM-based repository adapter for the User domain entity has been introduced, implementing the UserRepositoryPort interface. This change provides the concrete database operations for user data, including finding users by ID or email, counting users, and adding or updating user records, effectively bridging the application's domain model with the TypeORM persistence layer.
src/infrastructure/adapter/persistence/typeorm/repository/user · high confidence
Added TypeORM repository adapter for media persistence
A new TypeORM-based repository adapter has been introduced to handle media entity persistence. This adapter implements the MediaRepositoryPort, providing methods to find, count, add, update, and remove media records, including support for soft-deletion and query filtering by ID or owner.
src/infrastructure/adapter/persistence/typeorm/repository/media · high confidence
Added TypeORM-based post repository adapter
Introduced a new TypeORM implementation of the post repository, providing database persistence for post entities. This adapter handles finding, creating, updating, and removing posts, including soft-delete logic and query filtering by owner, status, and ID.
src/infrastructure/adapter/persistence/typeorm/repository/post · high confidence
Added build automation script
A new 'build.sh' script has been added to the 'scripts' directory. This Bash script automates the build process by clearing the dist directory, compiling TypeScript, copying package files, and installing production dependencies, streamlining the build workflow for users.
scripts · high confidence
Added dependency injection tokens for post domain
Introduced PostDITokens to define dependency injection (DI) tokens for the post domain. This includes tokens for use cases (Create, Edit, Get, Publish, Remove), a post image removed event handler, and a post repository, enabling the application's DI container to resolve these dependencies.
src/core/domain/post/di · high confidence
Added handler for post image removal
A new service, HandlePostImageRemovedEventService, has been introduced to process MediaRemovedEvent. When an image is removed, this handler updates the corresponding posts by clearing the imageId field, ensuring that posts no longer reference deleted media.
src/core/service/post/handler · high confidence
Added media query handlers for existence and preview checks
New query handlers, DoesMediaExistQueryHandler and GetMediaPreviewQueryHandler, have been introduced in the media domain. These handlers implement the QueryHandler interface to support querying media existence and retrieving media previews, utilizing the updated common/message structure for queries and results.
src/core/domain/media/handler · high confidence
Added media query service handlers
New query service handlers have been introduced for media operations, specifically for checking media existence and retrieving media previews. These services implement their respective query handlers by delegating to the media repository port, enabling the system to process media-related queries.
src/core/service/media/handler · high confidence
Added media use-case adapters for CRUD operations
New adapter classes have been added to the infrastructure layer to handle media use cases, including CreateMediaAdapter, EditMediaAdapter, GetMediaAdapter, GetMediaListAdapter, and RemoveMediaAdapter. Each adapter implements a specific port (e.g., CreateMediaPort, EditMediaPort) and includes validation logic for fields like executorId, mediaId, name, type, and file. These adapters serve as the bridge between the domain layer and the infrastructure layer, ensuring that media-related use cases are properly validated and executed.
src/infrastructure/adapter/usecase/media · high confidence
Added media use-case services
New service classes have been introduced to handle media use cases, including CreateMediaService, EditMediaService, GetMediaService, GetMediaListService, and RemoveMediaService. These services implement their respective use-case interfaces and interact with the media repository and event bus to manage media entities, including file storage, access control, and event publishing.
src/core/service/media/usecase · high confidence
Added post use-case adapters for content management
New adapter classes have been introduced in the infrastructure layer to handle post-related use cases, including CreatePostAdapter, EditPostAdapter, GetPostAdapter, GetPostListAdapter, PublishPostAdapter, and RemovePostAdapter. Each adapter implements a specific port (e.g., CreatePostPort, EditPostPort) and includes validation logic for fields such as executorId, postId, title, content, and imageId. This change enables the application to process and validate post operations through a consistent adapter pattern.
src/infrastructure/adapter/usecase/post · high confidence
Added transactional use-case wrapper
A new wrapper class, TransactionalUseCaseWrapper, has been added to the transaction infrastructure. It implements the UseCase interface and wraps a TransactionalUseCase, automatically executing onCommit and onRollback callbacks via the typeorm-transactional-cls-hooked library's runOnTransactionCommit and runOnTransactionRollback hooks during the execute method.
src/infrastructure/transaction · medium confidence
Added user creation and retrieval adapters
New adapter classes, CreateUserAdapter and GetUserAdapter, have been introduced in the infrastructure layer to handle user creation and retrieval use cases. These adapters implement their respective ports, utilize class-transformer and class-validator for data validation and transformation, and extend UseCaseValidatableAdapter to ensure input validation before processing.
src/infrastructure/adapter/usecase/user · high confidence
Added user service layer with query and use-case implementations
Introduced new service-layer components for user management: a query handler (HandleGetUserPreviewQueryService) that retrieves user previews, and use-case services (CreateUserService, GetUserService) that handle user creation and retrieval respectively. These files implement domain interfaces and interact with the user repository to manage user data, establishing the service layer for user-related operations.
src/core/service/user · medium confidence
Implemented post management use cases
Added new use-case services for creating, editing, retrieving, publishing, and removing posts. These services handle business logic such as validating user access, checking media availability, and updating the post repository, exposing a consistent interface for post-related operations.
src/core/service/post/usecase · high confidence
Initial database schema migrations for media, posts, and users
Added three new TypeORM migration files that create the initial database tables for media, posts, and users. The media table stores file metadata including type, path, and size. The posts table includes title, content, status (draft or published), and an optional image reference. The users table stores account details such as name, email, password, and role (admin, author, or guest). These migrations establish the foundational data structures required for the application's core entities.
src/infrastructure/adapter/persistence/typeorm/migration · high confidence
Initial project scaffolding and configuration
The repository is initialized with essential configuration files that establish the development and testing environment. This includes TypeScript and ESLint configurations (tsconfig.json, .eslintrc) to enforce code quality and module resolution, Jest settings (jest.json) for running unit tests, and Docker Compose files (docker-compose.local.yaml, docker-compose.test.yaml) to provision local PostgreSQL and Minio services. Additionally, an ORM configuration (ormconfig.json) is added to define database connection details and migration paths.
(repo-wide) · high confidence
Introduce FileMetadata value object for media domain
A new FileMetadata value object has been added to the media domain, encapsulating file metadata such as relative path, size, extension, and MIME type. This value object includes validation constraints and a static factory method to ensure data integrity when creating file metadata instances.
src/core/domain/media/value-object · high confidence
Introduce MediaUseCaseDto for media domain data transfer
Added MediaUseCaseDto, a new data transfer object for the media domain that exposes specific fields (id, ownerId, name, type, url, createdAt, editedAt) and provides static methods to map Media entities to DTOs for use cases.
src/core/domain/media/usecase/dto · high confidence
Introduce NestJS-based server application with Swagger API documentation
The application entry point (src/Main.ts) and the new ServerApplication class (src/application/ServerApplication.ts) now use the NestJS framework to start the server. The server configuration (host and port) is read from ApiServerConfig rather than being hardcoded. Additionally, the application automatically generates and serves Swagger API documentation at the '/documentation' endpoint, including bearer token authentication details.
src/application · high confidence
Introduce PostUseCaseDto for post serialization
A new DTO, PostUseCaseDto, has been added to handle the serialization of Post entities for use-case interactions. This class maps internal domain objects—such as Post, PostOwner, and PostImage—into a structured output format, including owner details, image metadata, and timestamps, while excluding internal state via class-transformer decorators.
src/core/domain/post/usecase/dto · high confidence
Introduce REST API controllers for authentication, media, posts, and users
Added HTTP REST controllers for authentication (login), media (create, edit, get, remove), posts (create, edit, get, publish, remove), and user accounts (create, get current). Each controller exposes endpoints that map to existing use cases, with Swagger documentation models for request and response bodies. Authentication is enforced via guards and role-based access control (e.g., admin/author roles for media and post operations).
src/application/api/http-rest/controller · high confidence
Introduce media domain use-case interfaces
Added new TypeScript interfaces for media domain use cases, including CreateMediaUseCase, EditMediaUseCase, GetMediaListUseCase, GetMediaUseCase, and RemoveMediaUseCase. These interfaces extend either the standard UseCase or the TransactionalUseCase base, establishing the domain layer's contract for media operations.
src/core/domain/media/usecase · high confidence
Introduce media domain use-case ports
New interfaces for media use cases have been added to the core domain, defining the contracts for creating, editing, retrieving, and removing media items. These ports specify the required input parameters (such as executor ID, media ID, name, type, and file data) that the application's application layer must provide to interact with the media domain.
src/core/domain/media/port/usecase · high confidence
Introduce media persistence ports
New persistence ports have been added to the media domain: MediaFileStoragePort for uploading files and retrieving metadata, and MediaRepositoryPort for creating, reading, updating, and removing media entities.
src/core/domain/media/port/persistence · high confidence
Introduce modular dependency injection structure for application layers
The application's dependency injection has been restructured into distinct modules for authentication, infrastructure, media, posts, and users. The new RootModule aggregates these sub-modules, while each sub-module (AuthModule, InfrastructureModule, MediaModule, PostModule, UserModule) explicitly registers controllers, providers, and handlers. This change organizes the codebase by domain, making it easier to locate and manage the wiring for each feature area.
src/application/di · high confidence
Introduce post use-case ports for content management
Added new port interfaces for post use cases, including CreatePostPort, EditPostPort, GetPostPort, GetPostListPort, PublishPostPort, and RemovePostPort. These interfaces define the input contracts for creating, editing, retrieving, publishing, and deleting posts, establishing the domain boundaries for post-related operations.
src/core/domain/post/port/usecase · high confidence
Introduced Media domain entity and payload types
Added the core Media entity class along with its associated payload types (CreateMediaEntityPayload, EditMediaEntityPayload) within the media domain. The Media class implements soft-delete functionality via a removedAt timestamp and provides methods to edit name and metadata, with validation enforced through class-validator decorators.
src/core/domain/media/entity · high confidence
Introduces core infrastructure for validation, messaging, and error handling
Adds foundational classes and interfaces that standardize how the application handles errors, validates data, and processes messages. A new \CoreApiResponse\ class and \Code\ constants provide a consistent structure for API responses and error codes. Validation is centralized through \ClassValidator\ and \UseCaseValidatableAdapter\, which enforce data integrity before use cases execute. The update also introduces a message-passing architecture with \CommandBusPort\, \QueryBusPort\, and \EventBusPort\ interfaces, alongside specific query and command handlers for media and user domains. Additionally, base classes for entities and value objects are provided to support domain modeling.
src/core/common · high confidence
Introduces user domain model and use-case interfaces
Adds the core user entity with fields for name, email, role, and password, along with DTOs and port interfaces for creating and retrieving users. The change also introduces dependency injection tokens for the new use cases and query handler, establishing the internal structure for user management operations.
src/core/domain/user · high confidence
NestJS adapters for command, event, and query buses
The application now provides concrete implementations for the message bus ports using NestJS. Specifically, the codebase introduces three new adapter classes—NestCommandBusAdapter, NestEventBusAdapter, and NestQueryBusAdapter—which bridge the core message interfaces to the @nestjs/cqrs library.
src/infrastructure/adapter/message · high confidence
New type definitions for creating and editing posts
Added TypeScript type definitions for post creation and editing payloads. The new \CreatePostEntityPayload\ includes fields for the post owner, title, image, content, and various status/timestamps, while \EditPostEntityPayload\ defines the subset of fields (title, image, content) available for updates.
src/core/domain/post/entity/type · high confidence
Behavioural changes
Define PostRepositoryPort interface for persistence operations
The PostRepositoryPort interface is introduced to standardize how the Post domain interacts with persistence layers. It defines methods for finding posts by ID or owner/status, adding new posts, updating existing ones, and removing them, establishing a clear contract for repository implementations.
src/core/domain/post/port/persistence · medium confidence
Externalize configuration for API, Database, and File Storage services
Configuration values for the API server, database, and file storage are now read from environment variables rather than being hardcoded. This includes connection details, credentials, and feature flags, allowing the application to be configured without code changes.
src/infrastructure/config · high confidence
Introduce NestJS wrapper handlers for domain logic
The application now uses explicit NestJS wrapper classes (e.g., NestWrapperDoesMediaExistQueryHandler) to bridge the infrastructure layer with the core domain. Each wrapper implements a specific query or event handler interface (IQueryHandler, IEventHandler) and delegates execution to the corresponding domain handler via dependency injection. This change organizes the handler logic by domain (media, post, user) and aligns the infrastructure layer with the CQRS pattern provided by @nestjs/cqrs.
src/infrastructure/handler · medium confidence
Introduce post use-case interfaces with transactional support
The post domain now defines explicit use-case interfaces for Create, Edit, Get, Publish, and Remove operations. Read operations (Get, GetList) extend the standard UseCase base, while write operations (Create, Edit, Publish, Remove) extend the new TransactionalUseCase base, ensuring these commands execute within a transactional context.
src/core/domain/post/usecase · medium confidence
Rename LoggingInterceptor to NestHttpLoggingInterceptor
The HTTP logging interceptor has been renamed from LoggingInterceptor to NestHttpLoggingInterceptor to better reflect its NestJS-specific implementation. The interceptor logs HTTP method, request path, and processing time for each request.
src/application/api/http-rest/interceptor · high confidence
Fixes
Fix DI for CQERS adapters in TypeOrmDirectory
The TypeOrmDirectory module was added to the TypeORM persistence adapter, exporting the directory path. This change resolves a dependency injection issue for CQERS adapters by ensuring the correct directory reference is available for the adapter's configuration.
src/infrastructure/adapter/persistence/typeorm · low confidence
Test coverage
Add common test utilities and server setup; Add unit tests for CoreApiResponse; Add unit tests for ValueObject validation; Added e2e asset directory constant; Added e2e test fixtures for authentication, media, posts, and users; Added e2e test utilities for response assertions; Added end-to-end tests for authentication, media, and post management; Added unit tests for CoreAssert and ClassValidator utilities; Added unit tests for core common entities and adapters; Added unit tests for core message and exception handling; Added unit tests for domain entities and DTOs; Added unit tests for media and post services; Added unit tests for user service use cases.
Dependencies
Initial project setup with TypeScript, NestJS, and testing tooling
Added package.json and package-lock.json to the project, establishing the dependency graph for a TypeScript-based application using NestJS (v8.4.7), TypeORM, Passport, and various utility libraries. Development tooling including Jest, ESLint, and TypeScript is also included.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 48 → 46 (-2.0)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 94 → 94 (+0.0)
- Architecture 56 → 55 (-1.2)
- Maturity 49 → 49 (+0.0)
- Readiness 36 → 33 (-3.0)
- Security 59 → 70 (+10.6)
Resolved (64)
- Change coupling: CreatePostEntityPayload.ts ↔ EditPostEntityPayload.ts (src/core/domain/post/entity/type/CreatePostEntityPayload.ts)
- Change coupling: CreatePostService.ts ↔ EditPostService.ts (src/core/service/post/usecase/CreatePostService.ts)
- Change coupling: MediaController.ts ↔ PostController.ts (src/application/api/http-rest/controller/MediaController.ts)
- Coverage not included — suite not readable by the collector
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical vulnerability: [GHSA redacted] (package-lock.json)
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- …and 44 more
New (140)
- Coverage not measured — JavaScript/TypeScript suite
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Critical vulnerability: [GHSA redacted] (package-lock.json)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- …and 120 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
pvarentsov/typescript-clean-architecture was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 5c29c39e402c67105ca66ec4dd2a4cf84b285e39 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-b84573e22831.