Claude-skill-registry enforce-file-organization
Guide feature-based directory structure and file placement. Apply when creating new files or organizing code. Enforce naming conventions and import ordering for backend and frontend files.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/enforce-file-organization" ~/.claude/skills/majiayu000-claude-skill-registry-enforce-file-organization && rm -rf "$T"
manifest:
skills/data/enforce-file-organization/SKILL.mdsource content
File Organization Standards
CRITICAL: Maintain consistent, predictable file organization across the codebase.
Why This Exists
Poor organization:
- Makes code hard to find
- Slows down development
- Causes merge conflicts
- Creates confusion
Good organization makes code discoverable and maintainable.
When to Apply
Apply when:
- Creating new files
- Moving/renaming files
- Setting up new features
- Refactoring structure
How It Works
Directory Structure
Feature-Based Organization (Backend)
src/features/ ├── auth/ │ ├── controllers/ # HTTP request handlers (max 300 lines) │ ├── services/ # Business logic (max 300 lines) │ ├── repositories/ # Data access (max 300 lines) │ ├── models/ # Domain models (max 200 lines) │ ├── validators/ # Input validation (max 150 lines) │ ├── types/ # TypeScript types (max 100 lines) │ ├── utils/ # Feature utilities (max 200 lines) │ ├── tests/ # Feature tests │ └── index.ts # Public API exports │ ├── users/ # Another feature │ └── ... │ └── posts/ # Another feature └── ...
Shared Code
src/shared/ # Used by 2+ features ├── services/ │ ├── EmailService.ts (max 300 lines) │ ├── StorageService.ts (max 250 lines) │ └── CacheService.ts (max 250 lines) ├── utils/ │ ├── dateUtils.ts (max 200 lines) │ └── validationUtils.ts (max 200 lines) ├── types/ │ └── common.ts (max 150 lines) ├── constants/ │ ├── errorCodes.ts (max 100 lines) │ └── httpStatus.ts (max 100 lines) └── middleware/ ├── authMiddleware.ts (max 200 lines) └── errorHandler.ts (max 250 lines)
Core Infrastructure
src/core/ # Core infrastructure (rarely changes) ├── database/ │ ├── connection.ts (max 200 lines) │ ├── migrations/ │ └── seeders/ ├── config/ │ ├── app.ts (max 150 lines) │ └── database.ts (max 100 lines) ├── errors/ │ ├── AppError.ts (max 150 lines) │ └── ValidationError.ts (max 100 lines) └── interfaces/ # Core abstractions ├── IRepository.ts (max 100 lines) └── IService.ts (max 100 lines)
Frontend Organization (React)
src/features/ ├── auth/ │ ├── components/ # Feature-specific components │ │ ├── LoginForm.tsx (max 250 lines) │ │ └── RegisterForm.tsx (max 250 lines) │ ├── hooks/ # Feature hooks │ │ └── useAuth.ts (max 150 lines) │ ├── services/ # API calls │ │ └── authApi.ts (max 200 lines) │ ├── store/ # State management │ │ └── authSlice.ts (max 250 lines) │ └── types/ │ └── auth.types.ts (max 100 lines) │ └── posts/ └── ...
Shared UI Components
src/components/ # Shared UI components ├── ui/ # Base UI (buttons, inputs) │ ├── Button.tsx (max 150 lines) │ ├── Input.tsx (max 150 lines) │ └── Modal.tsx (max 200 lines) ├── forms/ # Form components │ ├── FormField.tsx (max 150 lines) │ └── FormError.tsx (max 100 lines) └── layouts/ # Layout components ├── AppLayout.tsx (max 250 lines) └── Header.tsx (max 200 lines)
File Naming Conventions
Backend (Node.js/TypeScript)
Controllers: UserController.ts, AuthController.ts Services: UserService.ts, EmailService.ts Repositories: UserRepository.ts, PostRepository.ts Models: User.ts, Post.ts, Comment.ts Validators: UserValidator.ts, PostValidator.ts Utils: dateUtils.ts, stringUtils.ts (camelCase) Types: user.types.ts, api.types.ts (lowercase + .types) Constants: httpStatus.ts, errorCodes.ts (camelCase) Tests: UserService.test.ts, AuthController.test.ts
Frontend (React/TypeScript)
Components: Button.tsx, LoginForm.tsx (PascalCase) Hooks: useAuth.ts, useDebounce.ts (camelCase with 'use') Utils: format.ts, validation.ts (camelCase) Types: auth.types.ts, user.types.ts (lowercase + .types) Styles: Button.module.css, LoginForm.module.css Tests: Button.test.tsx, LoginForm.test.tsx
Import Organization
Order imports in this sequence:
// 1. External dependencies (third-party packages) import React, { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import axios from 'axios'; // 2. Internal absolute imports (from src/) import { Button } from '@/components/ui/Button'; import { useAuth } from '@/features/auth/hooks/useAuth'; // 3. Relative imports from same feature import { LoginForm } from './components/LoginForm'; import { validateEmail } from './utils/validation'; // 4. Types import type { User } from '@/types/user.types'; import type { LoginFormData } from './types/auth.types'; // 5. Styles import styles from './Login.module.css';
File Structure Within Files
Service/Class Files
/** * FILE: UserService.ts * PURPOSE: Handles user business logic */ // ======================================== // IMPORTS // ======================================== import { injectable } from 'inversify'; import { UserRepository } from '../repositories/UserRepository'; import type { User, CreateUserDTO } from '../types/user.types'; // ======================================== // CONSTANTS // ======================================== const MAX_USERNAME_LENGTH = 50; const MIN_PASSWORD_LENGTH = 8; // ======================================== // TYPES // ======================================== interface UserServiceOptions { sendWelcomeEmail?: boolean; } // ======================================== // CLASS IMPLEMENTATION // ======================================== @injectable() export class UserService { // ---------------------------------- // Properties // ---------------------------------- private userRepository: UserRepository; // ---------------------------------- // Constructor // ---------------------------------- constructor(userRepository: UserRepository) { this.userRepository = userRepository; } // ---------------------------------- // Public Methods // ---------------------------------- /** * WHY: Creates new user accounts * WHEN: Called during registration * HOW: Validates, hashes password, saves to DB */ async createUser(data: CreateUserDTO): Promise<User> { // Implementation } // ---------------------------------- // Private Methods // ---------------------------------- private validateUserData(data: CreateUserDTO): void { // Implementation } } // ======================================== // HELPER FUNCTIONS (if needed) // ======================================== function formatUsername(username: string): string { return username.trim().toLowerCase(); }
React Component Files
/** * FILE: LoginForm.tsx * PURPOSE: User authentication form */ // ======================================== // IMPORTS // ======================================== import React, { useState } from 'react'; import { Button } from '@/components/ui/Button'; import type { LoginFormData } from '../types/auth.types'; import styles from './LoginForm.module.css'; // ======================================== // TYPES // ======================================== interface LoginFormProps { onSuccess?: () => void; redirectUrl?: string; } // ======================================== // COMPONENT // ======================================== /** * WHY: Provides reusable login form * WHEN: Use on login pages or modals * HOW: Manages form state, validates, calls auth service */ export function LoginForm({ onSuccess, redirectUrl }: LoginFormProps) { // ---------------------------------- // State // ---------------------------------- const [formData, setFormData] = useState<LoginFormData>({ email: '', password: '' }); // ---------------------------------- // Handlers // ---------------------------------- const handleSubmit = async (e: React.FormEvent) => { // Implementation }; // ---------------------------------- // Render // ---------------------------------- return ( <form onSubmit={handleSubmit} className={styles.form}> {/* JSX */} </form> ); } // ======================================== // HELPER FUNCTIONS // ======================================== function validateLoginForm(data: LoginFormData): Record<string, string> { const errors: Record<string, string> = {}; // Implementation return errors; }
When to Split Files
Split when:
- File exceeds 400 lines - Plan extraction before 500 limit
- Multiple responsibilities - Each file should have ONE purpose
- Reusable logic found - Extract utilities, hooks, services
- Hard to test - If mocking too much, split it
- Hard to navigate - If scrolling a lot, split it
Enforcement
Code quality auditor checks:
- ✅ Files in correct directories
- ✅ Naming conventions followed
- ✅ Import order correct
- ✅ File structure follows template
- ✅ No files exceed line limits
- ✅ Related files co-located
Quick Checklist
- File in correct feature/shared/core directory
- File name follows naming convention
- Imports organized in correct order
- File has proper header documentation
- Sections clearly marked with comments
- File doesn't exceed line limit