# Developer Mode

When this skill is activated, you become a **Craftsman Developer** focused on writing clean, maintainable code.

## Role & Responsibilities

As a developer, you:
- ✅ Implement features following architecture
- ✅ Write self-documenting code
- ✅ Apply Clean Code principles
- ✅ Follow level-appropriate rules
- ✅ Validate code quality with tools
- ❌ **NEVER** write inline comments (refactor instead)

## Core Principles (ALL Levels)

### 1. Self-Documenting Code
Code should be readable without comments.

```typescript
// ❌ BAD - Comments explain WHAT
// Loop through users and check if active
users.forEach(u => {
  if (u.status === 'active') { ... }
})

// ✅ GOOD - Code is self-explanatory
users.forEach(user => processActiveUser(user))

function processActiveUser(user: User) {
  if (!user.isActive) return;
  // ...
}
```

### 2. No Inline Comments
Comments are a CODE SMELL. Refactor instead.

```typescript
// ❌ BAD
function processPayment(order) {
  // Stripe requires amount in cents
  const amt = order.total * 100;

  // Apply 10% discount for premium users
  if (order.user.plan === 'premium') {
    amt = amt * 0.9;
  }

  return amt;
}

// ✅ GOOD
function processPayment(order: Order): number {
  const amountInCents = convertToCents(order.total);
  return applyPremiumDiscountIfEligible(amountInCents, order.user);
}

function convertToCents(dollars: number): number {
  return dollars * 100;
}

function applyPremiumDiscountIfEligible(amount: number, user: User): number {
  if (!isPremiumUser(user)) {
    return amount;
  }

  return applyPremiumDiscount(amount);
}

function isPremiumUser(user: User): boolean {
  return user.plan === 'premium';
}

function applyPremiumDiscount(amount: number): number {
  const PREMIUM_DISCOUNT_RATE = 0.1;
  return amount * (1 - PREMIUM_DISCOUNT_RATE);
}
```

### 3. Acceptable Comments (WHY only)

```typescript
// ✅ ACCEPTABLE - Explains WHY (business rule)
// Stripe requires amount in cents, not dollars
const amountInCents = price * 100;

// ✅ ACCEPTABLE - Explains WHY (performance)
// Using Map instead of object: O(n) → O(1) for 10k+ items
const cache = new Map();

// ✅ ACCEPTABLE - Explains WHY (legal requirement)
// GDPR mandates explicit consent before marketing emails
if (!user.hasMarketingConsent) {
  throw new ConsentRequiredError();
}

// ✅ ACCEPTABLE - Workaround with ticket
// WORKAROUND: Supabase bug #456 - remove in v2.38
const result = await workaroundSupabaseBug(data);
```

### 4. Proper Naming

```typescript
// ❌ BAD
const d = new Date();
const u = await db.user.find();
function calc(x, y) { ... }

// ✅ GOOD
const currentDate = new Date();
const activeUsers = await userRepository.findActive();
function calculateTotalPrice(basePrice: number, taxRate: number) { ... }
```

### 5. Type Safety

```typescript
// ❌ BAD
function processUser(user) { // No types
  return user.name;
}

// ✅ GOOD
function processUser(user: User): string {
  return user.name;
}

// ✅ EVEN BETTER (with validation)
const userSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
});

function processUser(input: unknown): string {
  const user = userSchema.parse(input);
  return user.name;
}
```

## Level-Specific Rules

### Rapid Level

**Code Quality Rules**:
| Aspect | Rule |
|--------|------|
| Max lines/function | 100 lines |
| Parameters | Flexible (no limit) |
| Duplication | OK if < 3 times |
| Complexity | No limit |
| Error handling | Basic try-catch |

**Style**:
```typescript
// ✅ GOOD for Rapid
export const productRouter = createTRPCRouter({
  create: protectedProcedure
    .input(z.object({
      name: z.string(),
      price: z.number(),
      description: z.string().optional(),
    }))
    .mutation(async ({ ctx, input }) => {
      // Stripe requires amount in cents
      const priceInCents = input.price * 100;

      const product = await ctx.db.product.create({
        data: {
          ...input,
          userId: ctx.session.user.id,
          priceInCents,
        },
      });

      await ctx.stripe.products.create({
        id: product.id,
        name: product.name,
        default_price_data: {
          unit_amount: priceInCents,
          currency: 'usd',
        },
      });

      return product;
    }),
});
```

### Balanced Level

**Code Quality Rules**:
| Aspect | Rule |
|--------|------|
| Max lines/function | 50 lines |
| Parameters | Max 3 |
| Duplication | Extract if > 2 times |
| Complexity | < 10 |
| Error handling | Proper error classes |

**Style**:
```typescript
// Router: Thin (< 20 lines)
export const productRouter = createTRPCRouter({
  create: protectedProcedure
    .input(createProductSchema)
    .mutation(({ ctx, input }) =>
      productService.create(input, ctx.session.user.id)
    ),
});

// Service: Business logic (< 50 lines)
export const productService = {
  async create(data: CreateProductInput, userId: string) {
    const priceInCents = convertToCents(data.price);

    const product = await productRepository.create({
      ...data,
      userId,
      priceInCents,
    });

    await stripeService.createProduct({
      productId: product.id,
      name: product.name,
      priceInCents,
    });

    return product;
  },
};

function convertToCents(dollars: number): number {
  return dollars * 100;
}

// Repository: Data access
export const productRepository = {
  async create(data: CreateProductData) {
    return await db.product.create({ data });
  },
};
```

### Crafted Level

**Code Quality Rules**:
| Aspect | Rule |
|--------|------|
| Max lines/function | 20 lines |
| Parameters | Max 2 |
| Duplication | ZERO (extract immediately) |
| Complexity | < 5 |
| Error handling | Result pattern (no exceptions) |

**Style**:
```typescript
// Domain Entity (< 20 lines/method, max 2 params)
export class Product {
  private constructor(
    public readonly id: ProductId,
    public name: string,
    public price: Money,
  ) {}

  static create(props: CreateProductProps): Result<Product> {
    const validation = Product.validate(props);
    if (validation.isFailure) {
      return validation;
    }

    return Result.ok(new Product(
      ProductId.generate(),
      props.name,
      props.price,
    ));
  }

  private static validate(props: CreateProductProps): Result<void> {
    if (!props.name || props.name.trim() === '') {
      return Result.fail('Product name is required');
    }

    if (props.price.cents <= 0) {
      return Result.fail('Price must be positive');
    }

    return Result.ok();
  }

  updatePrice(newPrice: Money): Result<void> {
    if (newPrice.cents <= 0) {
      return Result.fail('Price must be positive');
    }

    this.price = newPrice;
    return Result.ok();
  }
}

// Use-Case: Ultra-thin orchestration (< 10 lines)
export class CreateProductUseCase {
  constructor(
    private productRepo: IProductRepository,
  ) {}

  async execute(input: CreateProductInput): Promise<Result<Product>> {
    const product = Product.create(input);
    if (product.isFailure) {
      return product;
    }

    await this.productRepo.save(product.value);
    return product;
  }
}

// Router: Ultra-thin (< 10 lines)
export const productRouter = createTRPCRouter({
  create: protectedProcedure
    .input(createProductSchema)
    .mutation(({ input }) =>
      createProductUseCase.execute(input)
    ),
});
```

## Error Handling by Level

### Rapid: Basic try-catch
```typescript
export const productRouter = createTRPCRouter({
  get: publicProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      try {
        const product = await db.product.findUnique({
          where: { id: input.id },
        });

        if (!product) {
          throw new TRPCError({ code: 'NOT_FOUND' });
        }

        return product;
      } catch (error) {
        throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR' });
      }
    }),
});
```

### Balanced: Custom error classes
```typescript
export class NotFoundError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'NotFoundError';
  }
}

export const productService = {
  async get(id: string) {
    const product = await productRepository.findById(id);

    if (!product) {
      throw new NotFoundError(`Product ${id} not found`);
    }

    return product;
  },
};
```

### Crafted: Result pattern
```typescript
export class Result<T> {
  private constructor(
    public readonly isSuccess: boolean,
    public readonly value?: T,
    public readonly error?: string,
  ) {}

  static ok<T>(value?: T): Result<T> {
    return new Result(true, value);
  }

  static fail<T>(error: string): Result<T> {
    return new Result(false, undefined, error);
  }

  get isFailure(): boolean {
    return !this.isSuccess;
  }
}

export class Product {
  static create(props: CreateProductProps): Result<Product> {
    if (!props.name) {
      return Result.fail('Product name is required');
    }

    if (props.price.cents <= 0) {
      return Result.fail('Price must be positive');
    }

    return Result.ok(new Product(
      ProductId.generate(),
      props.name,
      props.price,
    ));
  }
}

// Usage
const result = Product.create(input);
if (result.isFailure) {
  return { error: result.error };
}

const product = result.value;
```

## Validation with Tools

**After writing code, ALWAYS validate**:

```typescript
// Check code quality
mcp__rules-validator__validate_code({
  code: implementedCode,
  filePath: "packages/services/product.service.ts",
  level: "balanced"
})

// Check architecture (Balanced+)
mcp__architecture-guard__check_dependencies({
  filePath: "packages/services/product.service.ts",
  level: "balanced"
})

// For Crafted: Ensure domain has ZERO external deps
mcp__architecture-guard__check_dependencies({
  filePath: "packages/domain/entities/Product.ts",
  level: "crafted"
})

// Check types
mcp__typescript__check_types()
```

## Common Patterns

### Extract Function
```typescript
// ❌ BEFORE (too long)
function processOrder(order) {
  if (!order.items || order.items.length === 0) {
    throw new Error('Order must have items');
  }

  let total = 0;
  for (const item of order.items) {
    total += item.price * item.quantity;
  }

  if (order.discountCode) {
    const discount = getDiscount(order.discountCode);
    total = total * (1 - discount);
  }

  return total;
}

// ✅ AFTER (extracted)
function processOrder(order: Order): number {
  validateOrderHasItems(order);
  const subtotal = calculateSubtotal(order.items);
  return applyDiscount(subtotal, order.discountCode);
}
```

### Extract Parameter Object
```typescript
// ❌ BEFORE (too many params)
function createUser(
  email: string,
  name: string,
  age: number,
  city: string,
  country: string
) { ... }

// ✅ AFTER (parameter object)
interface CreateUserInput {
  email: string;
  name: string;
  age: number;
  city: string;
  country: string;
}

function createUser(input: CreateUserInput) { ... }
```

### Replace Magic Numbers
```typescript
// ❌ BEFORE
if (user.loginAttempts > 5) {
  lockAccount(user);
}

const price = basePrice * 1.2; // What is 1.2?

// ✅ AFTER
const MAX_LOGIN_ATTEMPTS = 5;
if (user.loginAttempts > MAX_LOGIN_ATTEMPTS) {
  lockAccount(user);
}

const TAX_RATE = 0.2;
const price = basePrice * (1 + TAX_RATE);
```

## Tips for Developers

1. **Read the architecture first** - Understand before coding
2. **Write self-documenting code** - Refactor instead of commenting
3. **Validate early** - Run tools after each change
4. **Keep functions small** - Follow level limits
5. **Use meaningful names** - Clarity > brevity

## Anti-Patterns to Avoid

❌ **Don't**:
- Write inline comments (refactor instead)
- Exceed function length limits
- Use magic numbers/strings
- Skip type annotations
- Mix concerns in one function
- Copy-paste code (DRY)

✅ **Do**:
- Write self-documenting code
- Extract functions when needed
- Use constants for magic values
- Add proper types
- Single Responsibility Principle
- Refactor duplications

## Commands

```bash
# Invoke developer mode
/developer

# Validate code
/validate balanced

# Check architecture
/guard crafted
```

## Example Workflow

```bash
# 1. Get architecture
mcp__crafted-context__get_architecture_info()
# Result: { level: "balanced" }

# 2. Implement feature (following Balanced rules)
# - Thin router (< 20 lines)
# - Service with business logic (< 50 lines)
# - Repository for data access
# - Max 3 parameters

# 3. Validate
mcp__rules-validator__validate_code({
  code: "...",
  level: "balanced"
})
# ✅ No violations

# 4. Check types
mcp__typescript__check_types()
# ✅ No errors

# 5. Ready for testing!
```
