AgentSkillsCN

production-audit

为Next.js/NestJS应用进行全面的生产就绪审计。涵盖安全、性能、代码质量、无障碍性、SEO、错误处理以及运营就绪度等多个维度。

SKILL.md
--- frontmatter
name: production-audit
description: Comprehensive production readiness audit for Next.js/NestJS applications. Covers security, performance, code quality, accessibility, SEO, error handling, and operational readiness.
version: 1.3.0
author: SphereOS
license: MIT
tags: [Audit, Security, Performance, Code Quality, Production, Next.js, NestJS]
dependencies: []
allowed-tools: Read, Glob, Grep, Bash, Task, WebFetch
github-repo: gautam-lulla/claude-skills
skill-path: production-audit

FIRST: Check for Updates

Before proceeding, check if a newer version is available:

  1. Read local version from ~/.claude/skills/production-audit/SKILL.md frontmatter
  2. Fetch remote version: https://raw.githubusercontent.com/gautam-lulla/claude-skills/main/production-audit/SKILL.md
  3. Compare the version: field in both

If remote version > local version, use AskUserQuestion:

  • Question: "A newer version of p-audit is available. Current: [local] → Latest: [remote]. What would you like to do?"
  • Options:
    1. "Update and continue (Recommended)"
    2. "Continue with current version"
    3. "View changelog"

If user selects "Update and continue":

  • Fetch SKILL.md, CHANGELOG.md, LEARNINGS.md from GitHub raw URL
  • Save to ~/.claude/skills/production-audit/
  • Confirm: "Updated p-audit to version [X]. Proceeding..."

If user selects "View changelog":

  • Fetch and display https://raw.githubusercontent.com/gautam-lulla/claude-skills/main/production-audit/CHANGELOG.md
  • Then ask again

If versions match, proceed silently (no prompt).


Production Readiness Audit

This skill performs a comprehensive audit of a Next.js/NestJS application to ensure it is ready for production deployment. The audit covers security, performance, code quality, developer experience & code consistency (recommended for early-stage projects), accessibility, SEO, error handling, and operational readiness.


IMPORTANT: First Step - Select Project

Before running any audit checks, you MUST ask the user which project to audit using AskUserQuestion:

code
Use AskUserQuestion with:
- Question: "Which project should I run the production audit on?"
- Options:
  1. Current directory ([show actual pwd path])
  2. Enter a different path

If the user selects option 2 ("Enter a different path"), they will type the path. Use that path for all subsequent audit commands.

Store the selected project path and use it as the base path for ALL file searches, reads, and commands throughout the audit.


How to Use This Skill

Invoke with /production-audit and Claude will:

  1. Ask which project to audit (current directory or custom path)
  2. Read the project structure and configuration files
  3. Perform automated checks across all audit categories
  4. Generate a detailed report with findings
  5. Provide severity ratings (Critical, High, Medium, Low)
  6. Suggest fixes for each issue found

Audit Categories

  1. Software Architecture Audit
  2. Security Audit
  3. Performance Audit
  4. Code Quality Audit
  5. Developer Experience & Code Consistency AuditEarly-stage priority
  6. Error Handling Audit
  7. Accessibility Audit
  8. SEO Audit
  9. Environment & Configuration Audit
  10. Dependencies Audit
  11. Build & Deployment Audit
  12. Monitoring & Observability Audit

1. Software Architecture Audit

1.1 Project Structure & Organization

CheckSeverityWhat to Look For
Directory structureHighInconsistent or flat structure, no clear separation
Feature organizationMediumRelated files scattered across directories
Barrel exportsMediumMissing or inconsistent index.ts files
ColocationMediumRelated files not colocated (component + styles + tests)

Expected Next.js App Router Structure:

code
src/
├── app/                      # Routes and pages
│   ├── (marketing)/          # Route groups for layouts
│   │   ├── page.tsx
│   │   └── layout.tsx
│   ├── (dashboard)/
│   │   ├── page.tsx
│   │   └── layout.tsx
│   ├── api/                  # API routes
│   ├── layout.tsx            # Root layout
│   ├── error.tsx             # Error boundary
│   └── not-found.tsx         # 404 page
├── components/
│   ├── ui/                   # Primitive/atomic components
│   ├── blocks/               # Composite sections
│   └── layout/               # Layout components
├── lib/                      # Utilities and shared logic
│   ├── utils/                # Pure utility functions
│   ├── hooks/                # Custom React hooks
│   ├── context/              # React context providers
│   └── api/                  # API client/fetching layer
├── types/                    # TypeScript type definitions
├── config/                   # Configuration constants
└── styles/                   # Global styles

Audit Checklist:

  • Clear separation between app routes and reusable code
  • Components organized by type (ui/blocks/layout) or feature
  • Shared utilities in lib/ not scattered in components
  • Types centralized or colocated with relevant code
  • No business logic in page components (delegated to lib/)

1.2 Component Architecture

CheckSeverityWhat to Look For
Single ResponsibilityHighComponents doing too many things
Prop drillingHighProps passed through 3+ levels
Component sizeMediumComponents > 200-300 lines
Presentation vs ContainerMediumMixed data fetching and UI rendering
ReusabilityMediumDuplicate component logic

Component Hierarchy Pattern:

code
Pages (Route Components)
  └── Fetch data, handle routing
  └── Pass data to templates/blocks

Templates (Page-level layouts)
  └── Compose blocks into page structure
  └── No data fetching

Blocks (Section components)
  └── Self-contained sections (Hero, Features, etc.)
  └── Receive content as props

UI Components (Primitives)
  └── Button, Input, Card, etc.
  └── Purely presentational
  └── Design system atoms

Anti-patterns to Flag:

typescript
// ❌ BAD: Component doing too much
export function UserDashboard() {
  const [user, setUser] = useState(null);
  const [posts, setPosts] = useState([]);
  const [comments, setComments] = useState([]);
  const [notifications, setNotifications] = useState([]);
  // ... 300 lines of mixed concerns
}

// ✅ GOOD: Separated concerns
export function UserDashboard() {
  return (
    <DashboardLayout>
      <UserProfile />
      <UserPosts />
      <UserNotifications />
    </DashboardLayout>
  );
}

Audit Commands:

bash
# Find large components (>200 lines)
find src/components -name "*.tsx" -exec wc -l {} \; | awk '$1 > 200 {print}'

# Check for prop drilling patterns
grep -r "props\." --include="*.tsx" src/components | wc -l

1.3 Data Flow & State Management

CheckSeverityWhat to Look For
State locationHighGlobal state for local concerns
Server vs Client stateHighDuplicating server data in client state
Prop drilling depthMediumData passed through many component layers
State updatesMediumUnnecessary re-renders from state changes
Cache strategyMediumNo caching or over-caching

State Categories:

TypeWhere to StoreExample
Server stateReact Query / Apollo / Server ComponentsUser data, CMS content
Global UI stateContext or ZustandTheme, sidebar open
Local UI stateuseStateForm inputs, modals
URL statesearchParamsFilters, pagination
Form stateReact Hook Form / useFormStateForm values, validation

Data Flow Pattern (Next.js App Router):

code
Server Component (page.tsx)
  └── Fetch data from CMS/API
  └── Pass as props to children

Client Components (interactive parts only)
  └── Local UI state (useState)
  └── Form state (useFormState)
  └── NO data fetching (receive as props)

Anti-patterns to Flag:

typescript
// ❌ BAD: Fetching in client component
'use client';
export function ProductList() {
  const [products, setProducts] = useState([]);
  useEffect(() => {
    fetch('/api/products').then(res => res.json()).then(setProducts);
  }, []);
  // ...
}

// ✅ GOOD: Server component fetches, client receives
// page.tsx (Server Component)
export default async function ProductsPage() {
  const products = await getProducts();
  return <ProductList products={products} />;
}

// ProductList.tsx (Client Component for interactivity)
'use client';
export function ProductList({ products }: { products: Product[] }) {
  // Only UI state here
}

1.4 Separation of Concerns

CheckSeverityWhat to Look For
Business logic in componentsHighComplex logic mixed with JSX
API calls in componentsHighfetch/axios directly in components
Hardcoded valuesMediumMagic numbers/strings in components
Style logic in componentsLowComplex conditional styling inline

Layer Separation:

code
┌─────────────────────────────────────────────┐
│  Presentation Layer (components/)           │
│  - React components                         │
│  - UI rendering only                        │
│  - Receives data as props                   │
└─────────────────────────────────────────────┘
                    ↑ props
┌─────────────────────────────────────────────┐
│  Application Layer (app/, lib/hooks/)       │
│  - Page components                          │
│  - Custom hooks                             │
│  - Orchestrates data flow                   │
└─────────────────────────────────────────────┘
                    ↑ data
┌─────────────────────────────────────────────┐
│  Data Layer (lib/api/, lib/content/)        │
│  - API clients                              │
│  - Data fetching functions                  │
│  - Data transformation                      │
└─────────────────────────────────────────────┘
                    ↑ raw data
┌─────────────────────────────────────────────┐
│  External Services (CMS, APIs, DB)          │
└─────────────────────────────────────────────┘

Expected File Organization:

typescript
// lib/content/index.ts - Data fetching abstraction
export async function getPageContent(slug: string) { ... }
export async function getProducts() { ... }

// lib/utils/formatters.ts - Pure utility functions
export function formatPrice(amount: number) { ... }
export function formatDate(date: Date) { ... }

// lib/hooks/useCart.ts - Stateful logic
export function useCart() { ... }

// components/ui/Button.tsx - Presentational only
export function Button({ children, variant }) { ... }

1.5 API Design & Data Fetching

CheckSeverityWhat to Look For
Consistent fetching patternHighMixed fetch methods across codebase
Error handlingHighInconsistent or missing error handling
Loading statesMediumNo loading indicators
Caching strategyMediumNo caching or improper cache invalidation
Type safetyMediumUntyped API responses

Data Fetching Layer Pattern:

typescript
// lib/api/client.ts - Base API client
class APIClient {
  private baseUrl: string;

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl;
  }

  async get<T>(endpoint: string): Promise<T> {
    const response = await fetch(`${this.baseUrl}${endpoint}`);
    if (!response.ok) {
      throw new APIError(response.status, await response.text());
    }
    return response.json();
  }

  async post<T>(endpoint: string, data: unknown): Promise<T> {
    // ...
  }
}

// lib/api/products.ts - Domain-specific functions
export async function getProducts(): Promise<Product[]> {
  return apiClient.get<Product[]>('/products');
}

export async function getProduct(id: string): Promise<Product> {
  return apiClient.get<Product>(`/products/${id}`);
}

GraphQL Pattern (Apollo/SphereOS CMS):

typescript
// lib/queries/index.ts - Query definitions
export const GET_PAGE_CONTENT = gql`...`;

// lib/content/index.ts - Content fetching abstraction
export async function getPageContent(slug: string) {
  const client = getServerClient();
  const { data } = await client.query({
    query: GET_PAGE_CONTENT,
    variables: { slug },
  });
  return data?.page ?? null;
}

1.6 Type System Architecture

CheckSeverityWhat to Look For
Type coverageHighany types, missing types
Type organizationMediumTypes scattered or duplicated
API type safetyHighUntyped API responses
Component prop typesMediumMissing or incomplete prop interfaces
Discriminated unionsLowNot using for complex state

Type Organization Pattern:

typescript
// types/index.ts - Re-export all types
export * from './api';
export * from './content';
export * from './components';

// types/api.ts - API response types
export interface APIResponse<T> {
  data: T;
  meta: {
    total: number;
    page: number;
  };
}

export interface APIError {
  code: string;
  message: string;
}

// types/content.ts - CMS content types
export interface Page {
  id: string;
  slug: string;
  title: string;
  content: PageContent;
}

export interface PageContent {
  hero: HeroSection;
  sections: Section[];
}

// types/components.ts - Shared component types
export interface BaseComponentProps {
  className?: string;
  children?: React.ReactNode;
}

Type Inference Best Practices:

typescript
// ✅ GOOD: Infer from schema/API
type Product = Awaited<ReturnType<typeof getProduct>>;

// ✅ GOOD: Discriminated unions for state
type AsyncState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

// ✅ GOOD: Zod for runtime validation + type inference
const ProductSchema = z.object({
  id: z.string(),
  name: z.string(),
  price: z.number(),
});
type Product = z.infer<typeof ProductSchema>;

1.7 Dependency Injection & Testability

CheckSeverityWhat to Look For
Hard-coded dependenciesMediumDirect imports of external services
Global singletonsMediumModules with side effects on import
TestabilityMediumFunctions that can't be unit tested
Mocking difficultyLowTight coupling making mocks complex

Dependency Injection Pattern:

typescript
// ❌ BAD: Hard-coded dependency
export async function getProducts() {
  const response = await fetch('https://api.example.com/products');
  return response.json();
}

// ✅ GOOD: Injectable dependency
export function createProductService(apiClient: APIClient) {
  return {
    async getProducts() {
      return apiClient.get<Product[]>('/products');
    },
    async getProduct(id: string) {
      return apiClient.get<Product>(`/products/${id}`);
    },
  };
}

// Usage
const productService = createProductService(apiClient);

// Testing
const mockClient = { get: jest.fn() };
const testService = createProductService(mockClient);

1.8 Scalability Patterns

CheckSeverityWhat to Look For
Code splittingHighLarge bundles, no dynamic imports
Lazy loadingMediumAll components loaded upfront
Route-based splittingMediumNot using Next.js automatic splitting
Feature flagsLowNo mechanism for gradual rollouts

Code Splitting Patterns:

typescript
// ✅ Dynamic import for heavy components
const HeavyChart = dynamic(() => import('./HeavyChart'), {
  loading: () => <ChartSkeleton />,
  ssr: false, // If client-only
});

// ✅ Route groups for different layouts
app/
├── (marketing)/     # Marketing pages layout
│   ├── layout.tsx
│   └── page.tsx
├── (app)/           # App dashboard layout
│   ├── layout.tsx
│   └── dashboard/
└── (auth)/          # Auth layout
    ├── layout.tsx
    └── login/

// ✅ Parallel routes for complex UIs
app/
├── @modal/          # Modal slot
├── @sidebar/        # Sidebar slot
└── layout.tsx       # Composes slots

1.9 Design Patterns & Conventions

CheckSeverityWhat to Look For
Consistent patternsMediumDifferent approaches for same problem
Named exportsLowDefault exports everywhere
File namingLowInconsistent naming conventions
Import organizationLowMessy, unordered imports

Recommended Patterns:

Compound Components (for complex UI):

typescript
// Usage
<Accordion>
  <Accordion.Item>
    <Accordion.Trigger>Title</Accordion.Trigger>
    <Accordion.Content>Content</Accordion.Content>
  </Accordion.Item>
</Accordion>

Render Props / Children as Function:

typescript
<DataFetcher url="/api/users">
  {({ data, loading, error }) => (
    loading ? <Spinner /> : <UserList users={data} />
  )}
</DataFetcher>

Custom Hooks for Logic Reuse:

typescript
function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);
  useEffect(() => {
    const handler = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);
  return debouncedValue;
}

1.10 Architecture Checklist

Project Structure:

  • Clear directory organization (app/, components/, lib/, types/)
  • Consistent file naming convention
  • Related files colocated
  • Barrel exports (index.ts) for clean imports

Component Architecture:

  • Single responsibility per component
  • No prop drilling (use composition or context)
  • Components < 200 lines
  • Clear separation: UI components vs page components

Data Flow:

  • Server Components for data fetching
  • Client Components only for interactivity
  • Centralized data fetching layer (lib/content/ or lib/api/)
  • Proper state management (server state vs client state)

Separation of Concerns:

  • No business logic in components
  • No direct API calls in components
  • Utilities extracted to lib/
  • Types centralized in types/

Type Safety:

  • No any types
  • All API responses typed
  • All component props typed
  • Zod or similar for runtime validation

Scalability:

  • Dynamic imports for heavy components
  • Route-based code splitting
  • Feature organization supports team scaling

2. Security Audit

1.1 Environment Variables

CheckSeverityWhat to Look For
Secrets in codeCriticalAPI keys, passwords, tokens hardcoded in source files
.env in gitCritical.env, .env.local, .env.production not in .gitignore
NEXT_PUBLIC exposureHighSensitive values prefixed with NEXT_PUBLIC_ (exposes to client)
Missing env validationMediumNo runtime validation of required environment variables

Files to Check:

code
.env*
.gitignore
src/**/*.ts
src/**/*.tsx
next.config.js

Audit Commands:

bash
# Check for hardcoded secrets patterns
grep -r "sk_live\|sk_test\|api_key\|apikey\|secret\|password\|token" --include="*.ts" --include="*.tsx" --include="*.js" src/

# Check if .env files are gitignored
grep -E "^\.env" .gitignore

# List all NEXT_PUBLIC variables
grep -r "NEXT_PUBLIC_" --include="*.ts" --include="*.tsx" src/

Required Fixes:

  • All secrets stored in environment variables only
  • .env* files in .gitignore
  • Only non-sensitive values use NEXT_PUBLIC_ prefix
  • Environment variables validated at startup

1.2 Authentication & Authorization

CheckSeverityWhat to Look For
Auth on protected routesCriticalRoutes accessible without authentication
Session handlingHighInsecure session storage, missing expiration
CSRF protectionHighForms without CSRF tokens
Input validationHighUser input not validated/sanitized

Files to Check:

code
src/app/**/page.tsx
src/middleware.ts
src/lib/auth/

Checklist:

  • Protected routes have auth checks
  • Middleware validates authentication tokens
  • Sessions expire appropriately
  • User input is validated before use

1.3 HTTP Security Headers

HeaderSeverityRecommended Value
Strict-Transport-SecurityHighmax-age=31536000; includeSubDomains
X-Content-Type-OptionsMediumnosniff
X-Frame-OptionsMediumDENY or SAMEORIGIN
X-XSS-ProtectionLow1; mode=block
Content-Security-PolicyHighProject-specific CSP
Referrer-PolicyMediumstrict-origin-when-cross-origin

Files to Check:

code
next.config.js
vercel.json
middleware.ts

Example Configuration (next.config.js):

javascript
const securityHeaders = [
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'X-Frame-Options', value: 'DENY' },
  { key: 'X-XSS-Protection', value: '1; mode=block' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
];

module.exports = {
  async headers() {
    return [{ source: '/(.*)', headers: securityHeaders }];
  },
};

1.4 Data Exposure

CheckSeverityWhat to Look For
Over-fetchingHighGraphQL/API returning more data than needed
Console.log leaksMediumSensitive data logged to console
Source maps in prodMediumSource maps exposing code structure
Error message exposureMediumStack traces shown to users

Audit Commands:

bash
# Check for console.log statements
grep -r "console\." --include="*.ts" --include="*.tsx" src/

# Check source map configuration
grep -r "productionBrowserSourceMaps" next.config.js

3. Performance Audit

2.1 Bundle Size

CheckSeverityThreshold
First Load JSHigh< 100KB per route
Total bundle sizeMedium< 250KB gzipped
Large dependenciesMediumNo single dep > 50KB

Audit Commands:

bash
# Analyze bundle
npm run build
npx @next/bundle-analyzer

# Check bundle size
ls -la .next/static/chunks/

Common Issues:

  • Importing entire libraries (import _ from 'lodash' vs import debounce from 'lodash/debounce')
  • Large icon libraries
  • Unused dependencies
  • Missing code splitting

2.2 Image Optimization

CheckSeverityWhat to Look For
Next.js Image componentHighUsing <img> instead of <Image>
Image sizingMediumMissing width/height or sizes prop
Format optimizationMediumNot using WebP/AVIF
Lazy loadingLowAbove-fold images not prioritized

Files to Check:

code
src/components/**/*.tsx
src/app/**/*.tsx
next.config.js (images.remotePatterns)

Checklist:

  • All images use Next.js <Image> component
  • Remote image domains configured
  • Appropriate sizes prop for responsive images
  • priority set for LCP images
  • Images are appropriately compressed

2.3 Rendering Strategy

CheckSeverityWhat to Look For
Unnecessary client componentsHigh'use client' on components that don't need it
Missing static generationMediumDynamic pages that could be static
N+1 queriesHighMultiple sequential data fetches
Missing cachingMediumNo revalidation strategy

Files to Check:

code
src/app/**/page.tsx
src/lib/content/
src/lib/queries/

Checklist:

  • Server Components used by default
  • Client Components only where needed (interactivity, hooks)
  • Parallel data fetching with Promise.all()
  • Appropriate revalidate or dynamic settings
  • Streaming/Suspense for slow data

2.4 Core Web Vitals

MetricTargetSeverity if Failed
LCP (Largest Contentful Paint)< 2.5sHigh
FID (First Input Delay)< 100msHigh
CLS (Cumulative Layout Shift)< 0.1Medium
TTFB (Time to First Byte)< 800msMedium

Audit Commands:

bash
# Run Lighthouse
npx lighthouse http://localhost:3000 --output=json --output-path=./lighthouse-report.json

# Or use Chrome DevTools Lighthouse tab

Common Fixes:

  • LCP: Optimize hero images, preload fonts
  • FID: Reduce JavaScript, defer non-critical scripts
  • CLS: Set explicit dimensions on images/embeds
  • TTFB: Optimize server response, use CDN

4. Code Quality Audit

4.1 TypeScript Strict Mode

CheckSeverityWhat to Look For
Strict mode enabledHigh"strict": true in tsconfig.json
No any typesMediumExplicit or implicit any usage
No ts-ignoreMedium@ts-ignore or @ts-nocheck comments
Proper null handlingMediumMissing null checks

Files to Check:

code
tsconfig.json
src/**/*.ts
src/**/*.tsx

Audit Commands:

bash
# Check for any types
grep -r ": any" --include="*.ts" --include="*.tsx" src/

# Check for ts-ignore
grep -r "@ts-ignore\|@ts-nocheck" --include="*.ts" --include="*.tsx" src/

# Run type check
npx tsc --noEmit

Required tsconfig.json Settings:

json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  }
}

4.2 Linting & Formatting

CheckSeverityWhat to Look For
ESLint configuredMediumMissing or incomplete ESLint config
No lint errorsMediumnpm run lint fails
Prettier configuredLowInconsistent formatting
Pre-commit hooksLowNo husky/lint-staged

Audit Commands:

bash
# Run linting
npm run lint

# Check for ESLint config
cat .eslintrc.json || cat .eslintrc.js || cat eslint.config.js

4.3 Code Organization

CheckSeverityWhat to Look For
Component sizeMediumComponents > 300 lines
File organizationLowInconsistent file structure
Naming conventionsLowInconsistent naming
Dead codeLowUnused exports, functions, variables

Checklist:

  • Components are focused and single-purpose
  • Consistent file naming (kebab-case or PascalCase)
  • Logical folder structure
  • No commented-out code blocks
  • No unused imports

5. Developer Experience & Code Consistency Audit

Early-Stage Priority: This section is critical for new projects. Establishing clean, consistent patterns early prevents technical debt and makes the codebase easier to maintain as the team grows.

5.1 Module Structure Consistency

CheckSeverityWhat to Look For
Consistent module layoutHighModules organized differently (some flat, some nested)
Index/barrel exportsHighSome modules export via index.ts, others don't
File colocationHighRelated files scattered (entity separate from its DTOs)
Naming alignmentHighModule name doesn't match folder/file naming

Expected Module Structure (NestJS Example):

code
src/modules/
├── user/
│   ├── index.ts                 # Barrel export
│   ├── user.module.ts           # Module definition
│   ├── entities/
│   │   └── user.entity.ts
│   ├── dto/
│   │   ├── create-user.dto.ts
│   │   └── update-user.dto.ts
│   ├── services/
│   │   └── user.service.ts
│   ├── resolvers/               # or controllers/
│   │   └── user.resolver.ts
│   └── __tests__/               # or *.spec.ts colocated
│       └── user.service.spec.ts
├── auth/                        # Same structure
├── content/                     # Same structure
└── media/                       # Same structure

Anti-patterns to Flag:

code
❌ Inconsistent structure across modules:
modules/
├── user/
│   ├── user.service.ts          # Flat structure
│   ├── user.controller.ts
│   └── user.entity.ts
├── auth/
│   ├── services/                # Nested structure
│   │   └── auth.service.ts
│   ├── controllers/
│   │   └── auth.controller.ts
│   └── entities/
│       └── auth.entity.ts

❌ Missing index.ts in some modules but not others
❌ Some modules use singular names (user/) others plural (users/)

Audit Commands:

bash
# Compare module structures
for dir in src/modules/*/; do echo "=== $dir ===" && ls -la "$dir"; done

# Find modules missing index.ts
find src/modules -maxdepth 2 -type d ! -exec test -e '{}/index.ts' \; -print

# Check for inconsistent nesting
find src/modules -type f -name "*.service.ts" | head -10
find src/modules -type f -name "*.entity.ts" | head -10

5.2 Naming Convention Consistency

CheckSeverityWhat to Look For
File namingHighMixed kebab-case and PascalCase files
Class namingHighInconsistent suffixes (Service vs Svc, Controller vs Ctrl)
Variable namingMediumMixed camelCase and snake_case
Database columnsMediumInconsistent column naming (camelCase vs snake_case)
GraphQL fieldsMediumInconsistent field naming across types

Naming Conventions Matrix:

ElementConventionExample
Fileskebab-caseuser-profile.service.ts
ClassesPascalCase + SuffixUserProfileService
InterfacesPascalCase (no I prefix)UserProfile
VariablescamelCaseuserProfile
ConstantsSCREAMING_SNAKEMAX_RETRY_COUNT
Database tablessnake_case (plural)user_profiles
Database columnssnake_casecreated_at
GraphQL typesPascalCaseUserProfile
GraphQL fieldscamelCasecreatedAt
Enum valuesPascalCase or SCREAMING_SNAKEActive or ACTIVE

Anti-patterns to Flag:

typescript
// ❌ Inconsistent file naming
user-profile.service.ts    // kebab-case
UserProfile.entity.ts      // PascalCase
userProfile.dto.ts         // camelCase

// ❌ Inconsistent class suffixes
class UserService {}       // "Service"
class AuthSvc {}           // "Svc"
class ContentManager {}    // "Manager"

// ❌ Mixed conventions in same entity
@Entity('UserProfiles')    // PascalCase table
class UserProfile {
  @Column()
  firstName: string;       // camelCase property

  @Column({ name: 'last_name' })
  lastName: string;        // snake_case in DB, camelCase in code (OK)

  @Column()
  created_at: Date;        // snake_case property (inconsistent!)
}

Audit Commands:

bash
# Check for mixed file naming patterns
find src -name "*.ts" | xargs -I {} basename {} | sort | uniq -c | sort -rn

# Find files not following kebab-case
find src -name "*.ts" | grep -E "[A-Z]" | grep -v node_modules

# Check for inconsistent class suffixes
grep -r "class.*Service\|class.*Svc\|class.*Manager" --include="*.ts" src/

5.3 Import/Export Pattern Consistency

CheckSeverityWhat to Look For
Import organizationMediumUnordered, ungrouped imports
Barrel exportsHighInconsistent use of index.ts re-exports
Circular dependenciesCriticalModules importing each other
Relative vs absoluteMediumMixed import path styles
Named vs default exportsMediumInconsistent export style

Expected Import Order:

typescript
// 1. Node built-ins
import { readFile } from 'fs';

// 2. External packages (npm)
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';

// 3. Internal aliases (@/ paths)
import { DatabaseService } from '@/database';
import { BaseEntity } from '@/common';

// 4. Relative imports (parent first, then siblings)
import { UserEntity } from '../entities';
import { CreateUserDto } from './dto';

Anti-patterns to Flag:

typescript
// ❌ Deep relative imports (use barrel exports or aliases)
import { UserEntity } from '../../../modules/user/entities/user.entity';

// ❌ Importing from index when you could import directly (in same module)
import { UserService } from './index';  // Should be './user.service'

// ❌ Inconsistent export style within project
// file1.ts: export default class Foo {}
// file2.ts: export class Bar {}

// ❌ Circular dependency
// user.service.ts imports auth.service.ts
// auth.service.ts imports user.service.ts

Audit Commands:

bash
# Find potential circular dependencies
npx madge --circular src/

# Check for deep relative imports
grep -r "from '\.\./\.\./\.\." --include="*.ts" src/

# Find default exports (should use named exports for consistency)
grep -r "export default" --include="*.ts" src/

5.4 Error Handling Pattern Consistency

CheckSeverityWhat to Look For
Exception typesHighMixed custom and generic exceptions
Error messagesHighInconsistent error message format
Error codesMediumNo standardized error codes
Try-catch patternsHighInconsistent error handling approaches
Logging on errorsMediumSome errors logged, others not

Expected Error Pattern:

typescript
// Consistent custom exception hierarchy
// src/common/exceptions/
export class BaseException extends Error {
  constructor(
    public readonly code: string,
    message: string,
    public readonly statusCode: number = 500,
  ) {
    super(message);
  }
}

export class NotFoundException extends BaseException {
  constructor(resource: string, identifier: string) {
    super('NOT_FOUND', `${resource} with id '${identifier}' not found`, 404);
  }
}

export class ValidationException extends BaseException {
  constructor(message: string, public readonly errors: ValidationError[]) {
    super('VALIDATION_ERROR', message, 400);
  }
}

// Consistent usage across services
throw new NotFoundException('User', userId);
throw new ValidationException('Invalid input', errors);

Anti-patterns to Flag:

typescript
// ❌ Inconsistent exception throwing
// Service A:
throw new Error('User not found');

// Service B:
throw new NotFoundException('User not found');

// Service C:
throw new HttpException('User not found', 404);

// ❌ Inconsistent error message formats
throw new Error('user not found');           // lowercase
throw new Error('User Not Found');           // Title Case
throw new Error('USER_NOT_FOUND');           // SCREAMING
throw new Error('User with ID 123 not found'); // with ID
throw new Error('Cannot find user');         // different phrasing

Audit Commands:

bash
# Find all throw statements to check consistency
grep -r "throw new" --include="*.ts" src/ | head -30

# Check for generic Error usage (should use custom exceptions)
grep -r "throw new Error(" --include="*.ts" src/

# Find HttpException usage (check for consistency)
grep -r "HttpException\|NotFoundException\|BadRequestException" --include="*.ts" src/

5.5 Type Definition Consistency

CheckSeverityWhat to Look For
Type locationHighTypes scattered vs centralized
Interface vs TypeMediumInconsistent use of interface vs type
Optional propertiesMediumInconsistent use of ? vs undefined
Null handlingHighMixed null and undefined usage
DTO validationHighSome DTOs validated, others not

Expected Type Organization:

typescript
// Shared types in types/ or common/
// src/common/types/
export interface PaginationParams {
  page: number;
  limit: number;
}

export interface PaginatedResponse<T> {
  items: T[];
  total: number;
  page: number;
  totalPages: number;
}

// Module-specific types colocated
// src/modules/user/types/
export interface UserFilters {
  status?: UserStatus;
  role?: UserRole;
}

// Consistent DTO pattern
export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  name: string;

  @IsEmail()
  email: string;

  @IsOptional()
  @IsString()
  bio?: string;
}

Anti-patterns to Flag:

typescript
// ❌ Inconsistent interface vs type usage
interface User { ... }    // Some use interface
type Product = { ... }    // Others use type alias

// ❌ Inconsistent optional handling
interface Config {
  apiKey?: string;        // Optional with ?
  timeout: number | undefined;  // Optional with | undefined
  retries: number | null;       // Nullable (different meaning!)
}

// ❌ DTOs without validation in some modules
// user.dto.ts - has validation decorators
// product.dto.ts - no validation decorators

Audit Commands:

bash
# Check for interface vs type consistency
grep -r "^interface\|^export interface" --include="*.ts" src/ | wc -l
grep -r "^type\|^export type" --include="*.ts" src/ | wc -l

# Find DTOs without class-validator decorators
find src -name "*.dto.ts" -exec grep -L "@Is\|@Min\|@Max\|@Valid" {} \;

# Check for mixed null/undefined
grep -r "| null\|| undefined" --include="*.ts" src/ | head -20

5.6 Service Pattern Consistency

CheckSeverityWhat to Look For
Method namingHighInconsistent CRUD method names
Return typesHighSome return entities, others DTOs
Transaction handlingHighInconsistent transaction patterns
Dependency injectionMediumSome deps injected, others instantiated
Method signaturesMediumInconsistent parameter ordering

Expected Service Pattern:

typescript
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly eventEmitter: EventEmitter,  // Injected, not instantiated
  ) {}

  // Consistent CRUD naming
  async create(dto: CreateUserDto): Promise<User> { ... }
  async findAll(filters: UserFilters): Promise<User[]> { ... }
  async findOne(id: string): Promise<User> { ... }
  async findOneOrFail(id: string): Promise<User> { ... }  // Throws if not found
  async update(id: string, dto: UpdateUserDto): Promise<User> { ... }
  async remove(id: string): Promise<void> { ... }

  // Consistent parameter order: identifier first, then data
  async updateStatus(id: string, status: UserStatus): Promise<User> { ... }
}

Anti-patterns to Flag:

typescript
// ❌ Inconsistent CRUD naming across services
// UserService:
async create() {}
async getAll() {}
async getById() {}

// ProductService:
async createProduct() {}
async findAll() {}
async findOne() {}

// OrderService:
async add() {}
async list() {}
async fetch() {}

// ❌ Inconsistent return types
async findUser(id): Promise<User> {}      // Returns entity
async findProduct(id): Promise<ProductDto> {}  // Returns DTO

// ❌ Instantiating dependencies instead of injection
class UserService {
  private logger = new Logger();  // ❌ Should be injected
}

Audit Commands:

bash
# Compare method names across services
grep -r "async create\|async find\|async get\|async update\|async delete\|async remove" --include="*.service.ts" src/

# Check for new keyword in services (potential DI violation)
grep -r "new.*(" --include="*.service.ts" src/ | grep -v "new Date\|new Error\|new Map\|new Set"

5.7 Test Pattern Consistency

CheckSeverityWhat to Look For
Test file locationMediumMixed colocated and centralized tests
Test namingMediumInconsistent describe/it descriptions
Mock patternsHighDifferent mocking approaches per module
Setup/teardownMediumInconsistent beforeEach/afterEach usage
Coverage gapsHighSome modules tested, others not

Expected Test Pattern:

typescript
// Consistent test file naming: *.spec.ts (unit) or *.e2e-spec.ts (e2e)
// Colocated: user.service.spec.ts next to user.service.ts
// Or centralized: __tests__/user.service.spec.ts

describe('UserService', () => {
  let service: UserService;
  let repository: MockType<Repository<User>>;

  // Consistent setup
  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [
        UserService,
        {
          provide: getRepositoryToken(User),
          useFactory: repositoryMockFactory,
        },
      ],
    }).compile();

    service = module.get(UserService);
    repository = module.get(getRepositoryToken(User));
  });

  // Consistent describe structure
  describe('create', () => {
    it('should create a user with valid data', async () => { ... });
    it('should throw ValidationException for invalid email', async () => { ... });
  });

  describe('findOne', () => {
    it('should return user when found', async () => { ... });
    it('should throw NotFoundException when not found', async () => { ... });
  });
});

Anti-patterns to Flag:

typescript
// ❌ Inconsistent test descriptions
it('creates user')           // No "should"
it('should create a user')   // With "should"
it('user creation works')    // Different style

// ❌ Inconsistent mocking
// Test A: Uses jest.mock()
// Test B: Uses manual mock objects
// Test C: Uses @nestjs/testing mock factories

// ❌ Missing tests for some modules
// user.service.spec.ts ✓
// product.service.spec.ts ✓
// order.service.spec.ts ✗ (missing!)

Audit Commands:

bash
# Find modules missing tests
for service in $(find src -name "*.service.ts" | grep -v spec); do
  spec="${service%.ts}.spec.ts"
  [ ! -f "$spec" ] && echo "Missing: $spec"
done

# Check test description consistency
grep -r "it('" --include="*.spec.ts" src/ | head -20

5.8 Documentation & Comments Consistency

CheckSeverityWhat to Look For
JSDoc on public APIsMediumSome services documented, others not
README per moduleLowInconsistent module documentation
Inline commentsLowOver-commented or under-commented
TODO/FIXME trackingMediumStale TODOs, no tracking system

Expected Documentation Pattern:

typescript
/**
 * Service for managing user accounts and authentication.
 *
 * @remarks
 * All methods require the caller to have appropriate permissions.
 * User data is automatically scoped to the current tenant.
 */
@Injectable()
export class UserService {
  /**
   * Creates a new user account.
   *
   * @param dto - The user creation data
   * @returns The created user entity
   * @throws {ValidationException} When email is already taken
   * @throws {ForbiddenException} When caller lacks permission
   */
  async create(dto: CreateUserDto): Promise<User> { ... }
}

Anti-patterns to Flag:

typescript
// ❌ Obvious comments that don't add value
// Increment the counter
counter++;

// ❌ Outdated comments
// TODO: Implement validation (but validation exists)
// Returns user by ID (but method returns Promise<User[]>)

// ❌ Stale TODOs with no tracking
// TODO: Fix this later
// FIXME: Temporary hack
// HACK: Need to refactor

Audit Commands:

bash
# Find TODOs and FIXMEs
grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.ts" src/

# Check JSDoc coverage on services
grep -l "@Injectable" src/**/*.service.ts | while read f; do
  grep -q "/\*\*" "$f" && echo "✓ $f" || echo "✗ $f"
done

5.9 Code Duplication & DRY Violations

CheckSeverityWhat to Look For
Duplicate logicHighSame code copy-pasted across modules
Similar DTOsMediumNearly identical DTOs not shared
Repeated queriesMediumSame database queries in multiple places
Utility sprawlMediumSimilar helper functions scattered

Common Duplication Patterns:

typescript
// ❌ Pagination logic repeated
// user.service.ts
const skip = (page - 1) * limit;
const [items, total] = await this.repo.findAndCount({ skip, take: limit });
return { items, total, page, totalPages: Math.ceil(total / limit) };

// product.service.ts - same code!
const skip = (page - 1) * limit;
const [items, total] = await this.repo.findAndCount({ skip, take: limit });
return { items, total, page, totalPages: Math.ceil(total / limit) };

// ✅ Extract to shared utility
// common/utils/pagination.ts
export function paginate<T>(items: T[], total: number, page: number, limit: number) {
  return { items, total, page, totalPages: Math.ceil(total / limit) };
}

Audit Commands:

bash
# Find similar code blocks (using jscpd)
npx jscpd src/ --min-lines 5 --min-tokens 50

# Find duplicate string patterns
grep -roh "throw new.*Exception" --include="*.ts" src/ | sort | uniq -c | sort -rn

# Find similar method signatures
grep -r "async find.*(" --include="*.service.ts" src/

5.10 Developer Experience Checklist

Module Structure:

  • All modules follow identical directory structure
  • Barrel exports (index.ts) in every module
  • Related files colocated (entity + DTOs + tests)
  • Consistent module naming (singular vs plural)

Naming Conventions:

  • File naming follows single convention (kebab-case recommended)
  • Class suffixes consistent (Service, Controller, Resolver, etc.)
  • Database naming follows convention (snake_case recommended)
  • No mixed camelCase/snake_case in same layer

Code Patterns:

  • CRUD methods named consistently across all services
  • Error handling uses same exception hierarchy
  • All DTOs have validation decorators
  • Transaction patterns consistent

Imports & Exports:

  • Import order consistent (externals → internals → relatives)
  • No circular dependencies
  • No deep relative imports (use aliases or barrels)
  • Consistent use of named exports

Testing:

  • Every service has corresponding spec file
  • Test descriptions follow consistent pattern
  • Mock setup standardized across tests
  • No test files with skipped tests (.skip)

Documentation:

  • Public APIs have JSDoc comments
  • No stale TODO/FIXME comments
  • Module-level README if complex

Code Reuse:

  • No copy-pasted logic between modules
  • Common utilities extracted to shared location
  • Similar DTOs consolidated or inherited

6. Error Handling Audit

6.1 Error Boundaries

CheckSeverityWhat to Look For
Global error boundaryHighMissing app/error.tsx
Not found handlingMediumMissing app/not-found.tsx
Segment error boundariesLowMissing error.tsx in route segments

Required Files:

code
src/app/error.tsx        # Global error boundary
src/app/not-found.tsx    # 404 page
src/app/global-error.tsx # Root layout errors

Example error.tsx:

tsx
'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  );
}

6.2 API Error Handling

CheckSeverityWhat to Look For
Try-catch blocksHighUnhandled promise rejections
Error responsesMediumInconsistent error response format
LoggingMediumErrors not logged
User feedbackMediumSilent failures

Files to Check:

code
src/app/api/**/route.ts
src/lib/content/
src/lib/queries/

Checklist:

  • All async operations wrapped in try-catch
  • Consistent error response format
  • Errors logged with context
  • User-friendly error messages displayed
  • Retry logic for transient failures

6.3 Form Validation

CheckSeverityWhat to Look For
Client-side validationMediumForms submit without validation
Server-side validationHighAPI accepts invalid data
Error displayMediumValidation errors not shown to user

Checklist:

  • Required fields validated
  • Email/phone formats validated
  • Server validates all input (never trust client)
  • Clear error messages displayed
  • Form state preserved on error

7. Accessibility Audit

7.1 Semantic HTML

CheckSeverityWhat to Look For
Heading hierarchyHighSkipped heading levels (h1 → h3)
Landmark regionsMediumMissing main, nav, footer elements
Button vs linkMedium<div onClick> instead of button/link
ListsLowItems not in ul/ol

Audit Commands:

bash
# Check for div with onClick (should be button)
grep -r "div.*onClick\|span.*onClick" --include="*.tsx" src/

# Check heading usage
grep -r "<h[1-6]" --include="*.tsx" src/

7.2 ARIA & Labels

CheckSeverityWhat to Look For
Image alt textHighImages without alt attribute
Form labelsHighInputs without associated labels
ARIA labelsMediumInteractive elements without accessible names
Focus managementMediumFocus not managed in modals/dialogs

Audit Commands:

bash
# Check for images without alt
grep -r "<Image\|<img" --include="*.tsx" src/ | grep -v "alt="

# Check for inputs without labels
grep -r "<input\|<Input" --include="*.tsx" src/

7.3 Keyboard Navigation

CheckSeverityWhat to Look For
Tab orderHighIllogical tab order
Focus visibleHighFocus indicator removed
Keyboard trapsHighCan't escape modal with keyboard
Skip linksMediumNo skip to main content link

Checklist:

  • All interactive elements focusable
  • Visible focus indicators
  • Logical tab order
  • Escape closes modals
  • Skip link for main content

7.4 Color & Contrast

CheckSeverityWhat to Look For
Color contrastHighText contrast ratio < 4.5:1
Color-only infoMediumInformation conveyed only by color
Focus contrastMediumFocus indicator not visible

Tools:

  • Chrome DevTools Accessibility panel
  • axe DevTools extension
  • Lighthouse accessibility audit

8. SEO Audit

8.1 Meta Tags

CheckSeverityWhat to Look For
Title tagsHighMissing or duplicate titles
Meta descriptionsMediumMissing or too long (> 160 chars)
Open GraphMediumMissing OG tags for social sharing
Canonical URLsMediumMissing canonical for duplicate content

Files to Check:

code
src/app/layout.tsx
src/app/**/page.tsx
src/app/**/layout.tsx

Required Metadata:

tsx
// src/app/layout.tsx
export const metadata: Metadata = {
  title: {
    default: 'Site Name',
    template: '%s | Site Name',
  },
  description: 'Site description',
  openGraph: {
    title: 'Site Name',
    description: 'Site description',
    url: 'https://example.com',
    siteName: 'Site Name',
    type: 'website',
  },
  twitter: {
    card: 'summary_large_image',
  },
};

8.2 Structured Data

CheckSeverityWhat to Look For
JSON-LDMediumMissing structured data
Schema validityMediumInvalid schema markup
Relevant schemasLowMissing business-specific schemas

Common Schemas:

  • Organization
  • LocalBusiness
  • BreadcrumbList
  • Article
  • Product
  • FAQ

8.3 Technical SEO

CheckSeverityWhat to Look For
robots.txtMediumMissing or misconfigured
sitemap.xmlMediumMissing sitemap
Mobile-friendlyHighNot responsive
Page speedHighSlow loading

Required Files:

code
public/robots.txt
app/sitemap.ts (or sitemap.xml)

9. Environment & Configuration Audit

9.1 Environment Files

CheckSeverityWhat to Look For
.env.exampleMediumNo example env file for onboarding
Env validationMediumNo schema validation for env vars
Production valuesHighDev values in production config

Required Files:

code
.env.example          # Template with placeholder values
.env.local           # Local development (gitignored)
.env.production      # Production overrides (if needed)

Env Validation Example (using zod):

typescript
// src/lib/env.ts
import { z } from 'zod';

const envSchema = z.object({
  NEXT_PUBLIC_CMS_GRAPHQL_URL: z.string().url(),
  CMS_ORGANIZATION_ID: z.string().uuid(),
  NODE_ENV: z.enum(['development', 'production', 'test']),
});

export const env = envSchema.parse(process.env);

9.2 Next.js Configuration

CheckSeverityWhat to Look For
Image domainsHighRemote images not configured
RedirectsMediumOld URLs not redirecting
HeadersMediumSecurity headers not set
RewritesLowAPI proxying if needed

Files to Check:

code
next.config.js
next.config.mjs

10. Dependencies Audit

10.1 Security Vulnerabilities

CheckSeverityWhat to Look For
Known vulnerabilitiesCriticalnpm audit findings
Outdated packagesMediumMajor versions behind
Deprecated packagesMediumUsing deprecated libraries

Audit Commands:

bash
# Check for vulnerabilities
npm audit

# Check for outdated packages
npm outdated

# Update to latest (be careful)
npm update

10.2 Dependency Hygiene

CheckSeverityWhat to Look For
Unused dependenciesLowPackages in package.json not imported
Dev vs prod depsLowDev dependencies in production
Lock fileMediumMissing or outdated package-lock.json

Audit Commands:

bash
# Find unused dependencies
npx depcheck

# Verify lock file is in sync
npm ci

10.3 License Compliance

CheckSeverityWhat to Look For
License compatibilityMediumGPL dependencies in proprietary project
License documentationLowNo license documentation

Audit Commands:

bash
# Check licenses
npx license-checker --summary

11. Build & Deployment Audit

11.1 Build Process

CheckSeverityWhat to Look For
Build succeedsCriticalnpm run build fails
No build warningsMediumTypeScript/ESLint warnings in build
Build timeLowExcessively long builds

Audit Commands:

bash
# Run production build
npm run build

# Check build output
ls -la .next/

11.2 Deployment Configuration

CheckSeverityWhat to Look For
Vercel configMediumMissing vercel.json optimizations
Environment varsCriticalProduction env vars not set
Domain configHighCustom domain not configured
SSLCriticalHTTPS not enforced

Files to Check:

code
vercel.json
.vercelignore

11.3 CI/CD Pipeline

CheckSeverityWhat to Look For
Automated testsMediumNo tests run on PR
Lint checksMediumNo linting in CI
Preview deploymentsLowNo preview for PRs
Rollback planMediumNo rollback strategy

12. Monitoring & Observability Audit

12.1 Error Tracking

CheckSeverityWhat to Look For
Error serviceHighNo Sentry/similar configured
Source mapsMediumErrors not deobfuscated
Alert rulesMediumNo alerts for errors

Integration Check:

bash
# Check for Sentry
grep -r "sentry" package.json
grep -r "@sentry" src/

12.2 Analytics

CheckSeverityWhat to Look For
Analytics configuredMediumNo analytics tracking
Privacy complianceHighNo cookie consent
Performance monitoringMediumNo RUM (Real User Monitoring)

12.3 Logging

CheckSeverityWhat to Look For
Structured loggingMediumNo consistent log format
Log levelsLowEverything at same level
PII in logsHighSensitive data logged

Audit Report Template

After completing the audit, generate a report using this template:

markdown
# Production Readiness Audit Report

**Project:** [PROJECT_NAME]
**Date:** [DATE]
**Auditor:** Claude Code

## Summary

| Category | Critical | High | Medium | Low | Pass |
|----------|----------|------|--------|-----|------|
| Architecture | X | X | X | X | ✓/✗ |
| Security | X | X | X | X | ✓/✗ |
| Performance | X | X | X | X | ✓/✗ |
| Code Quality | X | X | X | X | ✓/✗ |
| **DX & Consistency** | X | X | X | X | ✓/✗ |
| Error Handling | X | X | X | X | ✓/✗ |
| Accessibility | X | X | X | X | ✓/✗ |
| SEO | X | X | X | X | ✓/✗ |
| Configuration | X | X | X | X | ✓/✗ |
| Dependencies | X | X | X | X | ✓/✗ |
| Build/Deploy | X | X | X | X | ✓/✗ |
| Monitoring | X | X | X | X | ✓/✗ |

**Overall Status:** [READY / NOT READY / CONDITIONAL]

## Critical Issues (Must Fix)

1. [Issue description]
   - **Location:** [file:line]
   - **Fix:** [recommended fix]

## High Priority Issues

1. [Issue description]
   - **Location:** [file:line]
   - **Fix:** [recommended fix]

## Medium Priority Issues

[List issues]

## Low Priority Issues

[List issues]

## Recommendations

[Additional recommendations for improvement]

Quick Audit Checklist

For a rapid assessment, verify these critical items:

Must Have (Critical)

  • No secrets in code
  • .env* files gitignored
  • npm run build succeeds
  • npm audit shows no critical vulnerabilities
  • Error boundaries in place
  • HTTPS enforced
  • Production env vars configured

Should Have (High)

  • Security headers configured
  • TypeScript strict mode
  • All images use Next.js Image
  • Core Web Vitals passing
  • Form validation (client + server)
  • Alt text on images
  • Meta tags configured
  • Error tracking configured

Nice to Have (Medium/Low)

  • Structured data
  • Sitemap
  • Analytics
  • Pre-commit hooks
  • CI/CD pipeline
  • Documentation

Version History

v1.2 (January 2026)

  • Added Developer Experience & Code Consistency Audit (Section 5)
  • Covers module structure, naming conventions, import/export patterns, error handling consistency, type definitions, service patterns, test patterns, documentation, and code duplication
  • Marked as "Early-stage priority" for new projects
  • 12 audit categories total

v1.1 (January 2026)

  • Added comprehensive Software Architecture Audit (Section 1)
  • 11 audit categories total

v1.0 (January 2026)

  • Initial production audit skill
  • 10 audit categories
  • Report template

End of Production Readiness Audit Skill