Claude Code Plugins

Community-maintained marketplace

Feedback

backend-dev-guidelines

@Hieubkav/wincellarCloneBackend
0
0

Node.js/Express/TypeScript microservices development. Layered architecture (routes → controllers → services → repositories), BaseController, error handling, Sentry monitoring, Prisma, Zod validation, dependency injection. USE WHEN creating routes, controllers, services, repositories, middleware, API endpoints, database access, error tracking.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name backend-dev-guidelines
description Node.js/Express/TypeScript microservices development. Layered architecture (routes → controllers → services → repositories), BaseController, error handling, Sentry monitoring, Prisma, Zod validation, dependency injection. USE WHEN creating routes, controllers, services, repositories, middleware, API endpoints, database access, error tracking.

When to Use

Creating routes, controllers, services, repositories, middleware, APIs, database queries, error handling.

Quick Checklist

New API Endpoint:

  • Route in routes/ with verb naming (getUser, createProduct)
  • Controller extends BaseController
  • Service in services/ with business logic
  • Repository in repositories/ with Prisma queries
  • Zod validation for request data
  • Error handling with AppError
  • Sentry integration for monitoring

Layered Architecture

Route → Controller → Service → Repository → Database
         ↓            ↓           ↓
     Validation   Business    Data Access
                   Logic

Responsibilities:

  • Routes: Define endpoints, attach middleware
  • Controllers: Handle HTTP (req/res), validation
  • Services: Business logic, orchestration
  • Repositories: Database queries only

BaseController Pattern

class BaseController {
  ok(res, data?) { return res.status(200).json(data); }
  created(res, data) { return res.status(201).json(data); }
  noContent(res) { return res.status(204).send(); }
  badRequest(res, message) { return res.status(400).json({ error: message }); }
  notFound(res, message) { return res.status(404).json({ error: message }); }
}

Error Handling

class AppError extends Error {
  constructor(message: string, public statusCode: number = 500) {
    super(message);
  }
}

// Throw in service
throw new AppError('User not found', 404);

// Global handler
app.use((err, req, res, next) => {
  Sentry.captureException(err);
  res.status(err.statusCode || 500).json({
    error: err.message || 'Internal server error',
  });
});

Validation with Zod

import { z } from 'zod';

const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2),
  age: z.number().min(18).optional(),
});

// In controller
const data = createUserSchema.parse(req.body); // Throws if invalid

Dependency Injection

// Container
const userRepo = new UserRepository();
const userService = new UserService(userRepo);
const userController = new UserController(userService);

// Register routes
router.get('/users/:id', asyncHandler((req, res) =>
  userController.getUser(req, res)
));

Async Handler Wrapper

const asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

router.get('/users', asyncHandler(async (req, res) => {
  const users = await userService.getAll();
  res.json(users);
}));

Sentry Integration

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: process.env.SENTRY_DSN });

// Auto-capture errors
app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.errorHandler());

// Manual capture
try {
  await riskyOperation();
} catch (error) {
  Sentry.captureException(error);
  throw error;
}

Middleware Pattern

// Auth middleware
const authMiddleware = async (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'Unauthorized' });
  
  try {
    req.user = await verifyToken(token);
    next();
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
};

router.use('/protected', authMiddleware);

TypeScript Tips

// DTOs
interface CreateUserDto {
  email: string;
  name: string;
  age?: number;
}

// Service return types
async getById(id: string): Promise<User | null> {}

// Strict null checks
const user = await repo.findById(id);
if (!user) throw new AppError('Not found', 404);
return user; // TS knows user is not null here

File Organization

src/
├── routes/
│   └── user.routes.ts
├── controllers/
│   └── UserController.ts
├── services/
│   └── UserService.ts
├── repositories/
│   └── UserRepository.ts
├── middleware/
│   └── auth.middleware.ts
├── types/
│   └── user.types.ts
└── utils/
    ├── AppError.ts
    └── asyncHandler.ts


References

Quick Patterns: read .claude/skills/fullstack/backend-dev-guidelines/references/quick-patterns.md Prisma Patterns: read .claude/skills/fullstack/backend-dev-guidelines/references/prisma-patterns.md Common Patterns: read .claude/skills/fullstack/backend-dev-guidelines/references/common-patterns.md