Specialising in technical restructuring, vendor consolidation, and hands-on leadership. I "tinker" in development to stay sharp—ensuring my strategies survive contact with reality.
Strategy • Transformation • Leadership • Vendor Management
Artifacts of experimentation. Built to test theories, learn frameworks, and solve real inefficiencies.
A complete project management SaaS built to explore the limits of serverless databases and real-time state management.
Challenge
Most project management tools are bloated. I wanted to see if I could build a collaborative, drag-and-drop Kanban system that felt instant and handled complex auth/permissions.
Outcome
Successfully deployed a Next.js 15 app with <100ms interaction times. Implemented a fully relational schema in Neon (Postgres) managed by Drizzle ORM.
// Server Action: Create Task
export async function createTask(data) {
const { userId } = await auth();
await db.insert(tasks).values({
...data,
createdBy: userId,
status: 'todo'
});
revalidatePath('/board');
}A unified financial command center aggregating data from multiple banking APIs into a single, coherent view.
Challenge
Fragmented financial data across multiple institutions makes it hard to see the big picture. CSV exports are manual and brittle.
Outcome
Built an automated pipeline using Python/FastAPI that normalizes transactions from TrueLayer. Provides instant, aggregated insights with zero manual entry.
# FastAPI Endpoint
@app.get("/transactions")
async def get_transactions(
user: User = Depends(get_current_user)
):
raw_data = truelayer.fetch(user.id)
df = pd.DataFrame(raw_data)
return normalize_categories(df)An autonomous coding assistant designed to refactor legacy codebases and generate documentation.
Challenge
Refactoring legacy code is high-risk and time-consuming. LLMs often hallucinate when lacking context.
Outcome
Developed a context-aware agent that parses entire file trees, builds a dependency graph, and proposes safe, atomic refactors. reduced manual review time by 60%.
// Agent Loop
while (goal !== 'completed') {
const context = await retrieveContext(goal);
const action = await llm.decide(context);
if (action.type === 'edit_file') {
await applyDiff(action.file, action.diff);
}
}Replacing brittle manual processes with systems that don't need babysitting. Focus on robust error handling and observability.
Using LLMs where they genuinely help: retrieval, triage, summarisation, drafting, classification — with strict guardrails.
Turning ideas into working software to test assumptions quickly. "Build to think" is my primary methodology.