I started with simple Java programs in university, emerged into the complex world of enterprise supply chain software, and now pursuing the frontier of AI development. Here is a reflection of my journey, complete with code snippets that characterize the phases along the way.
University Days: Learning the Basics
My coding journey began in university with Java. Like many students, I started with the classic:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
One of my first side projects was a simple inventory management system:
public class InventoryItem {
private String name;
private int quantity;
private double price;
public InventoryItem(String name, int quantity, double price) {
this.name = name;
this.quantity = quantity;
this.price = price;
}
public boolean isInStock() {
return quantity > 0;
}
public double getTotalValue() {
return quantity * price;
}
}
Little did I know this simple class would foreshadow my future in supply chain software!
Enterprise Development: Scaling Up
Moving into enterprise development, i got thrown into a large codebase that had evolved over many years. My employer had been developing a bespoke solution for a large Swedish furnishing company. The solution was running very large SQL transformation jobs, taking numerous ERP systems as input to build up network optimization and inventory management models. As a result of an ever increasing scope and business logic requirements, the codebase had become unnecerasily complex with procedures wrapping around procedures.
SELECT
w.warehouse_id,
w.name AS warehouse_name,
i.item_id,
i.description,
i.quantity_on_hand,
COALESCE(o.pending_orders, 0) AS pending_orders,
(i.quantity_on_hand - COALESCE(o.pending_orders, 0)) AS available_stock,
s.supplier_name,
s.lead_time_days,
CASE
WHEN i.quantity_on_hand = 0 THEN 'OUT_OF_STOCK'
WHEN i.quantity_on_hand < i.reorder_point THEN 'LOW_STOCK'
ELSE 'SUFFICIENT_STOCK'
END AS stock_status,
ROUND(
(i.quantity_on_hand::DECIMAL / NULLIF(i.max_capacity, 0)) * 100,
2
) AS capacity_utilization_pct
FROM
warehouses w
INNER JOIN inventory i ON w.warehouse_id = i.warehouse_id
LEFT JOIN (
SELECT
warehouse_id,
item_id,
SUM(quantity) AS pending_orders,
COUNT(DISTINCT customer_id) AS unique_customers,
MAX(created_at) AS latest_order_date
FROM orders
WHERE status = 'PENDING'
AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY warehouse_id, item_id
) o ON i.warehouse_id = o.warehouse_id
AND i.item_id = o.item_id
LEFT JOIN suppliers s ON i.primary_supplier_id = s.supplier_id
LEFT JOIN warehouse_zones z ON w.warehouse_id = z.warehouse_id
WHERE
i.quantity_on_hand < i.reorder_point
AND w.is_active = true
AND (
w.maintenance_schedule IS NULL
OR w.maintenance_schedule > CURRENT_DATE
)
AND z.temperature_celsius BETWEEN i.min_storage_temp AND i.max_storage_temp
HAVING
COALESCE(o.unique_customers, 0) >= 3
OR i.quantity_on_hand <= i.safety_stock_level
ORDER BY
w.warehouse_id,
stock_status DESC,
i.quantity_on_hand ASC,
s.lead_time_days ASC;
This experience taught me an important lesson about code isolation and testability - always design for testability from the start, because you rarely get the time to fix it later.
Also part of the learning experience came from working with Git and Azure DevOps in a large enterprise team. Developing features is more than writing performant and maintainable code. It's also about organizing development efforts for the solution work now and in the future.
The AI Frontier: Where I Am Now


For the past six months, I’ve been building agentic coding software. It's not just about automation anymore — it's about building systems that can understand context, reason over intent, and write coherent code. Here's an example of how one of my agents uses prompt templates to dynamically request completions from an LLM:
interface PromptTemplate {
systemPrompt: string;
userPrompt: string;
}
interface CompletionAgent {
model: LLMClient;
template: PromptTemplate;
async completeFunction(name: string, description: string, signature: string): Promise<string> {
const prompt = `
${this.template.systemPrompt}
${this.template.userPrompt
.replace("{function_name}", name)
.replace("{description}", description)
.replace("{signature}", signature)}
`;
const response = await this.model.complete({
prompt,
temperature: 0.7,
maxTokens: 256,
});
return response.code;
}
}
const agent = new CompletionAgent({
model: openAIClient,
template: {
systemPrompt: "You are an expert software engineer. Write idiomatic, efficient TypeScript functions.",
userPrompt: "Given a function called `{function_name}` that {description}, implement it. Signature:\n{signature}"
}
});
const result = await agent.completeFunction(
"filterValidEmails",
"filters out invalid email addresses from a list",
"function filterValidEmails(emails: string[]): string[]"
);
Looking Ahead
The emergence of AI in software development brings new challenges and opportunities. It's an exciting time to be in this field, as we figure out how to effectively combine traditional programming practices with these new capabilities. The technology landscape will continue to evolve. What matters is building a strong foundation in software engineering principles while staying adaptable to new tools and approaches as they emerge.