with one click
mx-review
// Review code for MX Space project conventions. Checks NestJS patterns, Drizzle ORM repositories, Zod schemas, API design, etc.
// Review code for MX Space project conventions. Checks NestJS patterns, Drizzle ORM repositories, Zod schemas, API design, etc.
Use when releasing mx-core server (apps/core), @mx-space/api-client, or @mx-space/cli (mxs) — version bump, changelog, git tag, Docker build, GitHub Release, and Dokploy redeploy. Triggers on "发版", "release a new version", "cut a release", "bump version", "publish api-client", "publish cli", "release mxs".
Use when an agent must inspect, draft, validate, edit, publish, unpublish, delete, or configure mx-space content through packages/cli or the mxs binary.
Author and review Drizzle SQL migrations safely for rolling deploys. Triggers when editing apps/core/src/database/schema/*.ts or apps/core/src/database/migrations/*.sql, when the user runs drizzle-kit generate, when "lint-migrations" reports a violation, or on prompts like "迁移", "改 schema", "alter table", "add a column", "drop column", "migration safety". Enforces the expand-contract pattern because mx-core ships rolling deploys (Dokploy, 2 replicas) where new and old pods coexist for tens of seconds during cutover.
MX Space API design conventions. Apply when writing controllers, API endpoints, or handling HTTP requests.
Create E2E test file for a specified module. Use when adding end-to-end tests for controllers or unit tests for services and repositories.
Create a new NestJS module with repository, service, controller, schema, and Drizzle table definition. Use when adding new feature modules, API endpoints, or business domains.
| name | mx-review |
| description | Review code for MX Space project conventions. Checks NestJS patterns, Drizzle ORM repositories, Zod schemas, API design, etc. |
| argument-hint | ["file-path"] |
Review code for project conventions. Target: $ARGUMENTS
@ApiController() instead of @Controller()PaginationResult<T> from repository (no special decorator needed)@Auth() decoratorEntityIdDto for path params)private readonly postRepository: PostRepository)ModuleRef and injection tokensscheduleManager.schedule()eventManager.emit() or eventManager.broadcast()BaseRepository from ~/processors/database/base.repository@Inject(PG_DB_TOKEN) db: AppDatabase constructor parameterthis.db.select().from(table).where(...))parseEntityId() / toEntityId() / toDbId()this.paginationOf(total, page, size) helper from BaseRepositoryPaginationResult<T> for paginated queriescreateZodDto() to create DTO classeszEntityId, zNonEmptyString, zCoerceInt)pgTable() in ~/database/schema/pkText() helper (Snowflake text IDs)refText() helpercreatedAt(), updatedAt(), or tsCol() helperspgTable()data and paginationBusinessExceptionPOST_SERVICE_TOKEN)@Global()createE2EApp to create test apppourData@Auth()Promise.allOffsetDto with before/after)attachCategory, attachRelated)// 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) {}
// Wrong - manually wrapping array
return { data: items }
// Correct - ResponseInterceptor auto-wraps
return items
// 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 })
}
// 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)
}
// 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))
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