Developer Kit
Code Complexity Auditor
Scores functions on cyclomatic complexity, cognitive load, and length, then flags thresholds exceeded and suggests refactoring into smaller testable units. Useful for preventing maintenance debt from rapidly generated code. Tech leads reviewing AI-assisted PRs, engineers maintaining code they did not originally write, platform teams enforcing a complexity budget across a portfolio of services. The most insidious failure mode is not broken code but unmaintainable code — 120-line functions with nested conditionals and eight parameters that work today but become expensive to debug in three months. Static complexity metrics catch these cases reliably, but most teams do not run them consistently. A pre-review auditor flags the functions most likely to accumulate technical debt and proposes specific decompositions.
One-Time Purchase
$19.99
Complexity Audit — src/services/checkout.ts
Summary
| Metric | Functions Scanned | Violations | Justifiable Exceptions | |---|---|---|---| | Cyclomatic Complexity (threshold: 10) | 14 | 3 | 1 | | Cognitive Complexity (threshold: 15) | 14 | 2 | 0 | | Parameter Count (threshold: 5) | 14 | 2 | 0 | | Function Length (threshold: 60 lines) | 14 | 4 | 1 |
Total unique functions flagged: 6
Refactoring required: 5
Accepted as justifiable exceptions: 1
Per-Function Findings
🔴 processCheckout — Severity: Critical
| Metric | Value | Threshold | Violated | |---|---|---|---| | Cyclomatic Complexity | 23 | 10 | ✅ | | Cognitive Complexity | 34 | 15 | ✅ | | Parameter Count | 3 | 5 | ❌ | | Length | 148 lines | 60 lines | ✅ |
Summary: processCheckout handles inventory validation, coupon application, tax calculation, payment gateway dispatch, and order record creation in a single function body. The deeply nested conditionals for coupon stacking rules alone account for 11 cyclomatic complexity points.
Refactor Proposal: Decompose into five focused functions. Each extracted function preserves the exact return types and side-effect contracts of the corresponding block.
// BEFORE (abbreviated to show structure)
async function processCheckout(cart: Cart, user: User, options: CheckoutOptions): Promise<OrderResult> {
// 148 lines: inventory check, coupon logic, tax, payment, order creation
}
// AFTER
async function processCheckout(cart: Cart, user: User, options: CheckoutOptions): Promise<OrderResult> {
await validateInventory(cart);
const discountedCart = await applyCoupons(cart, options.couponCodes);
const taxedCart = await applyTax(discountedCart, user.address);
const paymentResult = await dispatchPayment(taxedCart, user.paymentMethod);
return createOrderRecord(taxedCart, user, paymentResult);
}
async function validateInventory(cart: Cart): Promise<void> {
for (const item of cart.items) {
const stock = await inventoryService.getStock(item.sku);
if (stock < item.quantity) {
throw new InsufficientStockError(item.sku, stock, item.quantity);
}
}
}
async function applyCoupons(cart: Cart, couponCodes: string[]): Promise<Cart> {
let discountedCart = { ...cart };
for (const code of couponCodes) {
const coupon = await couponService.resolve(code);
discountedCart = coupon.apply(discountedCart);
}
return discountedCart;
}
async function applyTax(cart: Cart, address: Address): Promise<Cart> {
const taxRate = await taxService.getRateForAddress(address);
const taxAmount = cart.subtotal * taxRate;
return { ...cart, taxAmount, total: cart.subtotal + taxAmount };
}
async function dispatchPayment(cart: Cart, method: PaymentMethod): Promise<PaymentResult> {
return paymentGateway.charge({ amount: cart.total, currency: cart.currency, method });
}
async function createOrderRecord(cart: Cart, user: User, payment: PaymentResult): Promise<OrderResult> {
return orderRepository.create({ cart, userId: user.id, paymentId: payment.id, status: 'confirmed' });
}
Estimated complexity after refactor: processCheckout cyclomatic → 1, cognitive → 3.
🔴 applyDiscountRules — Severity: High
| Metric | Value | Threshold | Violated | |---|---|---|---| | Cyclomatic Complexity | 17 | 10 | ✅ | | Cognitive Complexity | 21 | 15 | ✅ | | Parameter Count | 6 | 5 | ✅ | | Length | 54 lines | 60 lines | ❌ |
Summary: Six parameters and deeply nested coupon-stacking conditionals. The loyaltyTier, promoCode, isEmployee, cartTotal, itemCount, and regionCode parameters indicate this function is making too many orthogonal decisions simultaneously.
Refactor Proposal: Introduce a DiscountContext value object to collapse parameters, and extract tier-specific logic into a strategy map.
// BEFORE
function applyDiscountRules(
loyaltyTier: string,
promoCode: string | null,
isEmployee: boolean,
cartTotal: number,
itemCount: number,
regionCode: string
): number { ... }
// AFTER
interface DiscountContext {
loyaltyTier: string;
promoCode: string | null;
isEmployee: boolean;
cartTotal: number;
itemCount: number;
regionCode: string;
}
// Public signature preserved via overload shim — no call-site changes required
function applyDiscountRules(
loyaltyTier: string,
promoCode: string | null,
isEmployee: boolean,
cartTotal: number,
itemCount: number,
regionCode: string
): number {
return applyDiscountRulesFromContext({ loyaltyTier, promoCode, isEmployee, cartTotal, itemCount, regionCode });
}
function applyDiscountRulesFromContext(ctx: DiscountContext): number {
const baseDiscount = resolveBaseDiscount(ctx);
const promoDiscount = resolvePromoDiscount(ctx.promoCode, ctx.cartTotal);
return Math.min(baseDiscount + promoDiscount, ctx.cartTotal);
}
function resolveBaseDiscount(ctx: DiscountContext): number {
if (ctx.isEmployee) return ctx.cartTotal * 0.20;
const tierRates: Record<string, number> = { gold: 0.15, silver: 0.10, bronze: 0.05 };
return ctx.cartTotal * (tierRates[ctx.loyaltyTier] ?? 0);
}
function resolvePromoDiscount(promoCode: string | null, cartTotal: number): number {
if (!promoCode) return 0;
const promo = promoRegistry.get(promoCode);
return promo ? promo.calculate(cartTotal) : 0;
}
Estimated complexity after refactor: applyDiscountRulesFromContext cyclomatic → 2, cognitive → 2.
🟡 buildOrderSummary — Severity: Medium
| Metric | Value | Threshold | Violated | |---|---|---|---| | Cyclomatic Complexity | 8 | 10 | ❌ | | Cognitive Complexity | 9 | 15 | ❌ | | Parameter Count | 4 | 5 | ❌ | | Length | 74 lines | 60 lines | ✅ |
Summary: Exceeds length threshold due to verbose inline formatting logic for currency, addresses, and item line rendering. Logic is linear with low branching — low risk, but extraction improves readability and independent testability.
Refactor Proposal: Extract formatting helpers. No behavioral change.
// BEFORE
function buildOrderSummary(order: Order, user: User, locale: string, currency: string): OrderSummary {
// 74 lines including inline currency formatting, address formatting, line item rendering
}
// AFTER
function buildOrderSummary(order: Order, user: User, locale: string, currency: string): OrderSummary {
return {
id: order.id,
placedAt: order.createdAt.toISOString(),
customer: formatCustomerName(user),
shippingAddress: formatAddress(user.address, locale),
lineItems: order.items.map(item => formatLineItem(item, locale, currency)),
totals: formatTotals(order, locale, currency),
};
}
function formatCustomerName(user: User): string {
return `${user.firstName} ${user.lastName}`.trim();
}
function formatAddress(address: Address, locale: string): string {
return addressFormatter.format(address, locale);
}
function formatLineItem(item: OrderItem, locale: string, currency: string): FormattedLineItem {
return {
sku: item.sku,
name: item.name,
quantity: item.quantity,
unitPrice: formatCurrency(item.unitPrice, locale, currency),
lineTotal: formatCurrency(item.unitPrice * item.quantity, locale, currency),
};
}
function formatTotals(order: Order, locale: string, currency: string): OrderTotals {
return {
subtotal: formatCurrency(order.subtotal, locale, currency),
tax: formatCurrency(order.taxAmount, locale, currency),
total: formatCurrency(order.total, locale, currency),
};
}
✅ resolvePaymentRouting — Severity: Justifiable Exception
| Metric | Value | Threshold | Violated | |---|---|---|---| | Cyclomatic Complexity | 19 | 10 | ✅ | | Cognitive Complexity | 14 | 15 | ❌ | | Parameter Count | 2 | 5 | ❌ | | Length | 58 lines | 60 lines | ❌ |
Justification: Cyclomatic complexity of 19 reflects a legitimate payment-routing state machine encoding 16 discrete gateway-selection rules mandated by regional financial compliance requirements. Each branch corresponds to a documented business rule with its own regulatory citation. Decomposing this function would distribute the rule set across multiple locations, increasing the risk of inconsistency. Cognitive complexity (14) remains below threshold, confirming the branching is structurally flat and readable. No refactor required. Recommend adding a rule-table comment block mapping each branch to its compliance document reference.
Prioritized Refactor Queue
| Priority | Function | Cyclomatic | Cognitive | Action |
|---|---|---|---|---|
| 1 | processCheckout | 23 | 34 | Decompose into 5 functions |
| 2 | applyDiscountRules | 17 | 21 | Introduce DiscountContext + strategy map |
| 3 | buildOrderSummary | 8 | 9 | Extract formatting helpers |
| — | resolvePaymentRouting | 19 | 14 | Accepted exception — no action |
View full sample →
All sales final. No refunds on digital products.
Includes support for Claude Code, Codex, and OpenClaw in the same license.
What You Get With This Skill
Scores functions on cyclomatic complexity, cognitive load, and length, then flags thresholds exceeded and suggests refactoring into smaller testable units. Useful for preventing maintenance debt from rapidly generated code.
All ClearPoint Nexus Skills Include
- Production-ready workflow packaging for three supported platforms.
- Reusable structure designed for repeatable operator tasks.
- Clear deliverable format, not just raw prompt output.
Related Skills
$19.99
One-time license
$19.99
One-time license
$19.99
One-time license