mx-review
community[skill]
Review code for MX Space project conventions. Checks NestJS patterns, Drizzle ORM repositories, Zod schemas, API design, etc.
$
/plugin install coredetails
MX Space Code Review
Review code for project conventions. Target: $ARGUMENTS
Review Checklist
1. Controller Conventions
- Uses
@ApiController()instead of@Controller() - Paginated endpoints return
PaginationResult<T>from repository (no special decorator needed) - Authenticated endpoints use
@Auth()decorator - Uses correct HTTP methods (GET/POST/PUT/DELETE)
- Parameter validation uses DTOs (e.g.,
EntityIdDtofor path params) - Return values follow response conventions (arrays auto-wrapped, objects returned directly)
2. Service Conventions
- Injects repository class directly (e.g.,
private readonly postRepository: PostRepository) - Circular dependencies resolved with
ModuleRefand injection tokens - Async tasks use
scheduleManager.schedule() - Events use
eventManager.emit()oreventManager.broadcast()
3. Repository Conventions
- Extends
BaseRepositoryfrom~/processors/database/base.repository - Uses
@Inject(PG_DB_TOKEN) db: AppDatabaseconstructor parameter - Uses Drizzle query builder (
this.db.select().from(table).where(...)) - ID boundaries validated with
parseEntityId()/toEntityId()/toDbId() - Pagination uses
this.paginationOf(total, page, size)helper fromBaseRepository - Returns
PaginationResult<T>for paginated queries
4. Schema (DTO) Conventions
- Uses Zod instead of class-validator
- Uses
createZodDto()to create DTO classes - Provides Partial DTO for update operations
- Uses project custom validators (e.g.,
zEntityId,zNonEmptyString,zCoerceInt)
5. Database Schema Conventions
- Uses Drizzle
pgTable()in~/database/schema/ - Primary keys use
pkText()helper (Snowflake text IDs) - Foreign keys use
refText()helper - Timestamps use
createdAt(),updatedAt(), ortsCol()helpers - Indexes defined in the third argument of
pgTable()
6. API Design Conventions
- RESTful naming (plural nouns)
- Correct status codes (200/201/204/400/401/404)
- Paginated responses include
dataandpagination - Error responses use
BusinessException
7. Module Registration Conventions
- Repository registered as provider in module
- Service and controller registered in module
- Cross-module access uses injection tokens (e.g.,
POST_SERVICE_TOKEN) - Global modules decorated with
@Global()
8. Test Conventions
- Controllers have corresponding E2E tests
- Uses
createE2EAppto create test app - Test data created in
pourData
9. Security Conventions
- Sensitive operations protected by
@Auth() - User input is validated
- Internal error details not exposed
- Sensitive info not logged
10. Performance Conventions
- Batch operations use
Promise.all - Large datasets use cursor-based pagination (
OffsetDtowithbefore/after) - Hot queries have caching
- Avoid N+1 queries — batch related lookups (e.g.,
attachCategory,attachRelated)
Common Issues
Issue 1: Using class-validator
// Wrong
import { IsString } from 'class-validator'
class CreateDto {
@IsString()
name: string
}
// Correct
import { z } from 'zod'
import { createZodDto } from 'nestjs-zod'
const Schema = z.object({ name: z.string() })
class CreateDto extends createZodDto(Schema) {}
Issue 2: Response not following conventions
// Wrong - manually wrapping array
return { data: items }
// Correct - ResponseInterceptor auto-wraps
return items
Issue 3: Circular Dependency
// Wrong - direct injection causes circular dependency
constructor(private readonly otherService: OtherService) {}
// Correct - use ModuleRef for lazy loading
private otherService: OtherService
constructor(private readonly moduleRef: ModuleRef) {}
onApplicationBootstrap() {
this.otherService = this.moduleRef.get(OTHER_SERVICE_TOKEN, { strict: false })
}
Issue 4: Not using EntityIdDto for path params
// Wrong - raw string param with no validation
@Get('/:id')
async get(@Param('id') id: string) {}
// Correct - validated entity ID
@Get('/:id')
async get(@Param() params: EntityIdDto) {
return this.service.findById(params.id)
}
Issue 5: Repository not validating ID boundaries
// Wrong - passing raw string to DB query
await this.db.select().from(posts).where(eq(posts.id, id))
// Correct - validate ID at repository boundary
const idBig = parseEntityId(id)
await this.db.select().from(posts).where(eq(posts.id, idBig))
Output Format
After review, output in the following format:
## Review Results
### Passed
- [x] Item 1
- [x] Item 2
### Needs Changes
- [ ] Issue description
- Location: `file:line`
- Suggestion: Change recommendation
### Optimization Suggestions
- Suggestion 1
- Suggestion 2
technical
- github
- mx-space/core
- stars
- 530
- license
- NOASSERTION
- contributors
- 33
- last commit
- 2026-05-29T06:39:36Z
- file
- .claude/skills/mx-review/SKILL.md