plugins/utopia-studio-cobuild-product/skills/typed-service-contracts/SKILL.md
Architecture standard for building robust, type-safe TypeScript services using the "Spec and Handler" pattern. Use when building CLIs, libraries, or complex business logic.
npx skillsauth add The-Utopia-Studio/skills typed-service-contractsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill defines a Vertical Slice Architecture backed by Design by Contract (DbC) principles. It treats application logic as rigorously defined Units of Work where inputs are parsed (not just validated) and errors are treated as values (Result Pattern) rather than exceptions.
spec.ts)The "Contract" or "Port". It defines the What. It must contain:
DiscriminatedUnion of Success | Failure.interface ConfigureSpec).handler.ts)The "Implementation" or "Adapter". It defines the How. It must:
Result type.spec.ts)Follow this template to define the boundaries.
import { z } from 'zod';
// 1. VALIDATION HELPERS (Reusable Refinements)
export const SafePathSchema = z.string()
.min(1)
.refine(p => !p.includes('..'), "No traversal allowed");
// 2. INPUT (The Command) - "Parse, don't validate"
export const MyTaskInputSchema = z.object({
path: SafePathSchema,
force: z.boolean().default(false),
});
export type MyTaskInput = z.infer<typeof MyTaskInputSchema>;
// 3. ERROR CODES (Exhaustive)
export const MyTaskErrorCode = z.enum([
'FILE_NOT_FOUND',
'PERMISSION_DENIED',
'UNKNOWN_ERROR'
]);
// 4. RESULT (The Monad)
export const MyTaskSuccess = z.object({
success: z.literal(true),
data: z.string(), // The output payload
});
export const MyTaskFailure = z.object({
success: z.literal(false),
error: z.object({
code: MyTaskErrorCode,
message: z.string(),
suggestion: z.string().optional(),
recoverable: z.boolean(),
})
});
export type MyTaskResult =
| z.infer<typeof MyTaskSuccess>
| z.infer<typeof MyTaskFailure>;
// 5. INTERFACE (The Capability)
export interface MyTaskSpec {
execute(input: MyTaskInput): Promise<MyTaskResult>;
}
handler.ts)Follow this template to implement the logic.
import { MyTaskSpec, MyTaskInput, MyTaskResult } from './spec.js';
import * as fs from 'fs';
export class MyTaskHandler implements MyTaskSpec {
async execute(input: MyTaskInput): Promise<MyTaskResult> {
try {
// 1. Business Logic
if (!fs.existsSync(input.path)) {
// 2. Explicit Error Return (No Throwing)
return {
success: false,
error: {
code: 'FILE_NOT_FOUND',
message: `Path does not exist: ${input.path}`,
recoverable: true
}
};
}
// 3. Success Return
return {
success: true,
data: 'Operation complete'
};
} catch (error) {
// 4. Safety Net: Catch unknown runtime errors
return {
success: false,
error: {
code: 'UNKNOWN_ERROR',
message: error instanceof Error ? error.message : String(error),
recoverable: false
}
};
}
}
}
Do not write monolithic tests. Split them into Contract Tests and Logic Tests.
Test the Bouncer. Ensure invalid data is rejected before it reaches the handler.
// spec.test.ts
import { MyTaskInputSchema } from './spec';
const invalidCases = [
{ val: '../etc/passwd', err: 'No traversal allowed' },
{ val: '', err: 'min(1)' },
];
test.each(invalidCases)('validates paths', ({ val, err }) => {
const result = MyTaskInputSchema.safeParse({ path: val });
expect(result.success).toBe(false);
});
Test the Chef. Mock external dependencies (fs, network) and assert the Result Object.
// handler.test.ts
import { MyTaskHandler } from './handler';
import { vi } from 'vitest'; // or jest
test('returns FILE_NOT_FOUND if path missing', async () => {
// MOCK
vi.mocked(fs.existsSync).mockReturnValue(false);
// EXECUTE
const handler = new MyTaskHandler();
const result = await handler.execute({ path: '/fake' });
// ASSERT (Check the Result Object)
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.code).toBe('FILE_NOT_FOUND');
}
});
development
Create professional equity research earnings update reports (8-12 pages, 3,000-5,000 words) analyzing quarterly results for companies already under coverage. Fast-turnaround format focusing on beat/miss analysis, key metrics, updated estimates, and revised thesis. Includes 1-3 summary tables and 8-12 charts. Use when user requests "earnings update", "quarterly update", "earnings analysis", "Q1/Q2/Q3/Q4 results", or post-earnings report.
development
Updates a presentation with new numbers — quarterly refreshes, earnings updates, comp rolls, rebased market data. Use whenever the user asks to "update the deck with Q4 numbers", "refresh the comps", "roll this forward", "swap in the new earnings", "change all the $485M to $512M", or any request to swap figures across an existing deck without rebuilding it.
development
Real DCF (Discounted Cash Flow) model creation for equity valuation. Retrieves financial data from SEC filings and analyst reports, builds comprehensive cash flow projections with proper WACC calculations, performs sensitivity analysis, and outputs professional Excel models with executive summaries. Use when users need to value a company using DCF methodology, request intrinsic value analysis, or ask for detailed financial modeling with growth projections and terminal value calculations.
tools
Build professional financial services data packs from various sources including CIMs, offering memorandums, SEC filings, web search, or MCP servers. Extract, normalize, and standardize financial data into investment committee-ready Excel workbooks with consistent structure, proper formatting, and documented assumptions. Use for M&A due diligence, private equity analysis, investment committee materials, and standardizing financial reporting across portfolio companies. Do not use for simple financial calculations or working with already-completed data packs.