Atlas / Skills / mx-space / Create Module

Create ModuleSAFE

skills/mx-space/create-module

AI-powered CMS core for personal blogs and creator websites, with AI summaries, translation, moderation, and writing workflows.

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
NOASSERTION
Stars
564
01

Overview

AI-powered CMS core for personal blogs and creator websites, with AI summaries, translation, moderation, and writing workflows.

Read from source at commit 81b3f9a4c850OBSERVED · 2026-10-14
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: create-module
description: 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.
argument-hint: <module-name>
disable-model-invocation: true
---

# Create NestJS Module (PostgreSQL / Drizzle)

Create a new NestJS module for Mix Space project. Module name: `$ARGUMENTS`

## Directory Structure

Create the following files under `apps/core/src/modules/<module-name>/`:

```
<module-name>/
├── <name>.module.ts       # Module definition
├── <name>.controller.ts   # HTTP controller
├── <name>.service.ts      # Business logic
├── <name>.repository.ts   # Drizzle repository (extends BaseRepository)
├── <name>.schema.ts       # Zod validation schemas for API DTOs
├── <name>.types.ts        # TypeScript row/input types
└── <name>.enum.ts         # Enums (optional, only if needed)
```

Also add the Drizzle table definition in `apps/core/src/database/schema/`.

## File Templates

### 0. Drizzle Table (`database/schema/<name>.ts`)

Create a new schema file (or append to an existing one) in `apps/core/src/database/schema/`.

```typescript
import { index, pgTable, text, uniqueIndex } from 'drizzle-orm/pg-core'

import { createdAt, pkText, refText, tsCol, updatedAt } from './columns'

export const <name>s = pgTable(
  '<name>s',
  {
    id: pkText(),
    createdAt: createdAt(),
    name: text('name').notNull(),
    // Add other columns...
  },
  (table) => [
    // Add indexes and unique constraints
    // uniqueIndex('<name>s_name_uniq').on(table.name),
    // index('<name>s_created_at_idx').on(table.createdAt),
  ],
)
```

Then re-export it from `apps/core/src/database/schema/index.ts`:

```typescript
export * from './<name>'
```

**Column helpers** (from `columns.ts`):

- `pkText()` — Snowflake primary key as text (auto-named `id`)
- `refText(name)` — Snowflake foreign-key reference as text
- `createdAt()` — `created_at` timestamp with default `now()`
- `updatedAt()` — `updated_at` nullable timestamp
- `tsCol(name)` — generic timestamp column

**Common column types**:

- `text('col')` — string
- `integer('col')` — number
- `boolean('col')` — boolean (use `.default(false)`)
- `jsonb('col').$type<T>()` — JSON data
- `text('col').array()` — text array (e.g., tags)

### 1. Types (`<name>.types.ts`)

```typescript
import type { EntityId } from '~/shared/id/entity-id'

export interface <Name>Row {
  id: EntityId
  name: string
  createdAt: Date
}

export interface <Name>CreateInput {
  name: string
}

export type <Name>PatchInput = Partial<<Name>CreateInput>
```

### 2. Repository (`<name>.repository.ts`)

```typescript
import { Inject, Injectable } from '@nestjs/common'
import { desc, eq, sql } from 'drizzle-orm'

import { PG_DB_TOKEN } from '~/constants/system.constant'
import { <name>s } from '~/database/schema'
import {
  BaseRepository,
  type PaginationResult,
  toEntityId,
} from '~/processors/database/base.repository'
import type { AppDatabase } from '~/processors/database/postgres.provider'
import { type EntityId, parseEntityId } from '~/shared/id/entity-id'
import { SnowflakeService } from '~/shared/id/snowflake.service'

import type { <Name>CreateInput, <Name>PatchInput, <Name>Row } from './<name>.types'

const mapRow = (row: typeof <name>s.$inferSelect): <Name>Row => ({
  id: toEntityId(row.id) as EntityId,
  name: row.name,
  createdAt: row.createdAt,
})

@Injectable()
export class <Name>Repository extends BaseRepository {
  constructor(
    @Inject(PG_DB_TOKEN) db: AppDatabase,
    private readonly snowflake: SnowflakeService,
  ) {
    super(db)
  }

  async list(
    page = 1,
    size = 10,
    filter?: Record<string, unknown>,
  ): Promise<PaginationResult<<Name>Row>> {
    page = Math.max(1, page)
    size = Math.min(50, Math.max(1, size))
    const offset = (page - 1) * size
    const [rows, [{ count }]] = await Promise.all([
      this.db
        .select()
        .from(<name>s)
        .orderBy(desc(<name>s.createdAt))
        .limit(size)
        .offset(offset),
      this.db.select({ count: sql<number>`count(*)::int` }).from(<name>s),
    ])
    return {
      data: rows.map(mapRow),
      pagination: this.paginationOf(Number(count ?? 0), page, size),
    }
  }

  async findAll(): Promise<<Name>Row[]> {
    const rows = await this.db
      .select()
      .from(<name>s)
      .orderBy(desc(<name>s.createdAt))
    return rows.map(mapRow)
  }

  async findById(id: EntityId | string): Promise<<Name>Row | null> {
    const idBig = parseEntityId(id)
    const [row] = await this.db
      .select()
      .from(<name>s)
      .where(eq(<name>s.id, idBig))
      .limit(1)
    return row ? mapRow(row) : null
  }

  async create(input: <Name>CreateInput): Promise<<Name>Row> {
    const id = this.snowflake.nextId()
    const [row] = await this.db
      .insert(<name>s)
      .values({
        id,
        name: input.name,
      })
      .returning()
    return mapRow(row)
  }

  async update(
    id: EntityId | string,
    patch: <Name>PatchInput,
  ): Promise<<Name>Row | null> {
    const idBig = parseEntityId(id)
    const update: Partial<typeof <name>s.$inferInsert> = {}
    if (patch.name !== undefined) update.name = patch.name
    if (Object.keys(update).length === 0) {
      const [existing] = await this.db
        .select()
        .from(<name>s)
        .where(eq(<name>s.id, idBig))
        .limit(1)
      return existing ? mapRow(existing) : null
    }
    const [row] = await this.db
      .update(<name>s)
      .set(update)
      .where(eq(<name>s.id, idBig))
      .returning()
    return row ? mapRow(row) : null
  }

  async deleteById(id: EntityId | string): Promise<<Name>Row | null> {
    const idBig = parseEntityId(id)
    const [row] = await this.db
      .delete(<name>s)
      .where(eq(<name>s.id, idBig))
      .returning()
    return row ? mapRow(row) : null
  }

  async count(): Promise<number> {
    const [row] = await this.db
      .select({ cou
03

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (1)

MEDIUMInventory / provenance · inv.symlink · CWE-1104
apps/core/.env
apps/core/.env
Why it matters. link not followed

Gates applied: no_behavioural_pass.

Audited 2026-10-14 · audit v0.4.1 · source sha 81b3f9a4c850full audit observations/trust-audit/skill/mx-space__create-module.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-1481b3f9a4c850SAFEB89first audit
05

Questions

What does the Create Module skill do?

AI-powered CMS core for personal blogs and creator websites, with AI summaries, translation, moderation, and writing workflows.

Is Create Module safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can Create Module access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (81b3f9a4c850), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement