Back to Skills

create-mockdb-repository

majiayu000
Updated Today
58
9
58
View on GitHub
Metatestingdata

About

This skill generates an in-memory MockDB repository implementation using arrays for data storage, ideal for development and testing scenarios. It creates a TypeScript file with CRUD operations, UUID generation, and filtering capabilities when you need a mock database or test fixtures. Use it to quickly implement repository interfaces without external dependencies during prototyping or testing.

Quick Install

Claude Code

Recommended
Plugin CommandRecommended
/plugin add https://github.com/majiayu000/claude-skill-registry
Git CloneAlternative
git clone https://github.com/majiayu000/claude-skill-registry.git ~/.claude/skills/create-mockdb-repository

Copy and paste this command in Claude Code to install this skill

Documentation

Create MockDB Repository

Creates an in-memory repository implementation using an array as the data store. Ideal for development, testing, and prototyping.

Quick Reference

Location: src/repositories/mockdb/{entity-name}.mockdb.repository.ts Naming: {entity-name}.mockdb.repository.ts (e.g., note.mockdb.repository.ts)

Instructions

Step 1: Create the Implementation File

Create src/repositories/mockdb/{entity-name}.mockdb.repository.ts

Step 2: Import Dependencies

import { v4 as uuidv4 } from "uuid";
import type {
  {Entity}Type,
  Create{Entity}Type,
  Update{Entity}Type,
  {Entity}QueryParamsType,
  {Entity}IdType,
} from "@/schemas/{entity-name}.schema";
import {
  DEFAULT_LIMIT,
  DEFAULT_PAGE,
  type PaginatedResultType,
} from "@/schemas/shared.schema";
import type { I{Entity}Repository } from "@/repositories/{entity-name}.repository";
import type { UserIdType } from "@/schemas/user.schemas";

Step 3: Create the Class

export class MockDb{Entity}Repository implements I{Entity}Repository {
  private {entities}: {Entity}Type[] = [];

  // Helper method for filtering, pagination, and sorting
  private applyQueryParams(
    {entities}: {Entity}Type[],
    params: {Entity}QueryParamsType,
  ): PaginatedResultType<{Entity}Type> {
    let filtered = {entities};

    // Apply entity-specific filters
    if (params.createdBy) {
      filtered = filtered.filter((item) => item.createdBy === params.createdBy);
    }

    // Apply search filter
    const searchTerm = params.search?.toLowerCase().trim();
    if (searchTerm) {
      filtered = filtered.filter((item) =>
        item.{searchableField}.toLowerCase().includes(searchTerm)
      );
    }

    // Pagination
    const page = params.page ?? DEFAULT_PAGE;
    const limit = params.limit ?? DEFAULT_LIMIT;
    const skip = (page - 1) * limit;
    let paginated = filtered.slice(skip, skip + limit);
    const totalPages = Math.ceil(filtered.length / limit);

    // Sorting
    const sortBy = (params.sortBy ?? "createdAt") as keyof {Entity}Type;
    const sortOrder = params.sortOrder;
    if (sortBy) {
      paginated = paginated.sort((a, b) => {
        if (sortOrder === "asc") {
          return a[sortBy]?.toString().localeCompare(b[sortBy]?.toString() ?? "") ?? 0;
        } else if (sortOrder === "desc") {
          return b[sortBy]?.toString().localeCompare(a[sortBy]?.toString() ?? "") ?? 0;
        }
        return 0;
      });
    }

    return {
      data: paginated,
      total: filtered.length,
      page,
      limit,
      totalPages,
    };
  }

  async findAll(params: {Entity}QueryParamsType): Promise<PaginatedResultType<{Entity}Type>> {
    return this.applyQueryParams(this.{entities}, params);
  }

  async findById(id: {Entity}IdType): Promise<{Entity}Type | null> {
    const item = this.{entities}.find((e) => e.id === id);
    return item || null;
  }

  async findAllByIds(
    ids: {Entity}IdType[],
    params: {Entity}QueryParamsType,
  ): Promise<PaginatedResultType<{Entity}Type>> {
    const filtered = this.{entities}.filter((item) => ids.includes(item.id));
    return this.applyQueryParams(filtered, params);
  }

  async create(
    data: Create{Entity}Type,
    createdByUserId: UserIdType,
  ): Promise<{Entity}Type> {
    const now = new Date();
    const new{Entity}: {Entity}Type = {
      id: uuidv4(),
      ...data,
      createdBy: createdByUserId,
      createdAt: now,
      updatedAt: now,
    };
    this.{entities}.push(new{Entity});
    return new{Entity};
  }

  async update(id: {Entity}IdType, data: Update{Entity}Type): Promise<{Entity}Type | null> {
    const index = this.{entities}.findIndex((e) => e.id === id);
    if (index === -1) {
      return null;
    }
    const existing = this.{entities}[index];
    const updated = {
      ...existing,
      ...data,
      updatedAt: new Date(),
    };
    this.{entities}[index] = updated;
    return updated;
  }

  async remove(id: {Entity}IdType): Promise<boolean> {
    const initialLength = this.{entities}.length;
    this.{entities} = this.{entities}.filter((e) => e.id !== id);
    return this.{entities}.length < initialLength;
  }

  // Helper method for testing: clear all data
  clear(): void {
    this.{entities} = [];
  }
}

Patterns & Rules

Class Naming

  • Class name: MockDb{Entity}Repository (e.g., MockDbNoteRepository)
  • Implements: I{Entity}Repository interface

Private Data Store

private {entities}: {Entity}Type[] = [];

Use a descriptive plural name for the array (e.g., notes, courses, users).

ID Generation

Use uuid for generating unique IDs:

import { v4 as uuidv4 } from "uuid";

// In create method:
id: uuidv4(),

Timestamp Handling

Always set timestamps in create and update:

// Create
const now = new Date();
createdAt: now,
updatedAt: now,

// Update
updatedAt: new Date(),

The applyQueryParams Helper

This private method handles:

  1. Filtering - Entity-specific filters (createdBy, status, etc.)
  2. Search - Text search on searchable fields
  3. Pagination - Skip and limit calculations
  4. Sorting - Sort by field and order

Testing Helper

Always include a clear() method for test cleanup:

clear(): void {
  this.{entities} = [];
}

Complete Example

See REFERENCE.md for a full implementation example including:

  • Complete MockDbNoteRepository class
  • Custom method example (findAllByIds)
  • Usage in tests with clear() helper

What NOT to Do

  • Do NOT add database connection logic - MockDB is in-memory only
  • Do NOT validate with Zod in MockDB - that's the MongoDB pattern for document mapping
  • Do NOT throw errors for not-found cases - return null/false
  • Do NOT forget the clear() helper - tests need it
  • Do NOT use synchronous methods - keep them async for interface compatibility

GitHub Repository

majiayu000/claude-skill-registry
Path: skills/create-mockdb-repository

Related Skills

content-collections

Meta

This skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.

View skill

evaluating-llms-harness

Testing

This Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.

View skill

cloudflare-turnstile

Meta

This skill provides comprehensive guidance for implementing Cloudflare Turnstile as a CAPTCHA-alternative bot protection system. It covers integration for forms, login pages, API endpoints, and frameworks like React/Next.js/Hono, while handling invisible challenges that maintain user experience. Use it when migrating from reCAPTCHA, debugging error codes, or implementing token validation and E2E tests.

View skill

llamaindex

Meta

LlamaIndex is a data framework for building RAG-powered LLM applications, specializing in document ingestion, indexing, and querying. It provides key features like vector indices, query engines, and agents, and supports over 300 data connectors. Use it for document Q&A, chatbots, and knowledge retrieval when building data-centric applications.

View skill