Author: Daniel

  • Random Conversation Turned Into A Real Product

    My schoolmate and I were chatting about how a EMR (SaaS) he has been using for a while, felt cluttered.

    The cluttered UI kept popping up in conversations over time. One day, our causal chat turned in to a requirement gathering session in a restaurant.

    I happened to talk a developer friend about the cluttered UI. Sparked by the idea, the developer friend wanted to join hands.

    Four weeks later, the developer friend and I turned the idea in to a working demo. The schoolmate, after seeing the demo, was impressed.

    Now, we’re turning the demo in to reality, talking about compliance auditing and SaaS pricing. We’re all excited to see how things turn out for us. This is quite a learning for all three of us.

    Our story is quite similar to Tokenn which I read in LinkedIn recently.

  • S.O.L.I.D Principles In Software Engineering

    Robert C. Martin, an American software engineer, author and instructor promoted the idea of S.O.L.I.D design principles in Software engineering.

    S.O.L.I.D, a set of five software design principles, helps you to write maintainable, scalable (without performance degradation), testable and extendable code (addition of new features/functionality).

    The Five S.O.L.I.D Pricinples

    1. Single Responsibility principle
    2. Open/Closed principle
    3. Liskov Substitution principle
    4. Interface Segregation principle
    5. Dependency Inversion pricinple

    1. Single Responsibility Principle

    A class must have single responsibility. Imagine you’re building an ecommerce application. The OrderService class handles multiple responsibilities — Order generation, sending emails & invoice generation.

    Bad Design

    class OrderService {
      createOrder() {
        // Save order to database
      }
    
      sendEmail() {
        // Send confirmation email
      }
    
      generateInvoice() {
        // Generate PDF invoice
      }
    }

    The same can be turned in to single responsibility classes in the following manner. Now each class has a clearly defined responsibility.

    Good Design

    class OrderService {
      createOrder() {
        // Create order
      }
    }
    
    class EmailService {
      sendEmail() {
        // Send confirmation email
      }
    }
    
    class InvoiceService {
      generateInvoice() {
        // Generate invoice
      }
    }

    Why It Matters?

    In case the email provider changes, we only need to modify the EmailService class and not the rest.

    2. Open/Closed Principle

    Software entities must be open for extension and closed for modification. Imagine the same e-commerce Application supports different payment integrations.

    Bad Design

    class PaymentService {
      pay(method: string) {
        if (method === "stripe") {
          // Stripe payment
        } else if (method === "paypal") {
          // PayPal payment
        }
      }
    }

    Each time a new payment integration is required, PaymentService must be modified. This is bad design. the same can be turned into the following.

    Good Design

    interface PaymentGateway {
      pay(amount: number): void;
    }
    
    class StripePayment implements PaymentGateway {
      pay(amount: number) {
        console.log("Stripe:", amount);
      }
    }
    
    class PayPalPayment implements PaymentGateway {
      pay(amount: number) {
        console.log("PayPal:", amount);
      }
    }
    
    class PaymentService {
      constructor(private gateway: PaymentGateway) {}
    
      process(amount: number) {
        this.gateway.pay(amount);
      }
    }

    By combining interfaces and single responsible classes, you can then use the classes like below:

    const payment = new PaymentService(
      new StripePayment()
    );
    
    payment.process(1000);

    Why It Matters?

    PaymentService doesn’t need to be modified in order to add a new payment gateway provider and is considered closed. The above system is open to the addition of new payment providers.

    3. Liskov Substitution Pricinple

    Take a look at the following example. A subclass must be usable whenever its parent’s class is expected without breaking the behaviour.

    In ReadOnlyStorage, save() is inherited but not fulfilled.

    Bad Design

    class FileStorage {
      save(file: string) {
        console.log("Saving:", file);
      }
    }
    
    class ReadOnlyStorage extends FileStorage {
      save(file: string) {
        throw new Error("Cannot save");
      }
    }

    Good Design

    interface ReadableStorage {
      read(): string;
    }
    
    interface WritableStorage {
      save(file: string): void;
    }
    
    class CloudStorage
      implements ReadableStorage, WritableStorage {
      read() {
        return "file contents";
      }
    
      save(file: string) {
        console.log("Saved:", file);
      }
    }
    
    class ReadOnlyStorage implements ReadableStorage {
      read() {
        return "file contents";
      }
    }

    In this case, ReadOnlyStorage fulfils the contract and so is the CloudStorage.

    Why It Matters?

    The substitutions read() and save() are implemented without breaking the contract.

    4. Interface Segregation Principle

    Clients (Class, modules or components) should not be forced to depend on methods they don’t use. Look at the following example. When a class implements `Worker`, all methods are forced.

    Bad Design

    interface Worker {
      code(): void;
      design(): void;
      test(): void;
    }

    In this case, the contract is forced.

    class Developer implements Worker {
      code() {
        console.log("Writing code");
      }
    
      design() {
        throw new Error("Not supported");
      }
    
      test() {
        throw new Error("Not supported");
      }
    }

    Good Design

    interface Developer {
      code(): void;
    }
    
    interface Designer {
      design(): void;
    }
    
    interface Tester {
      test(): void;
    }
    
    class FrontendEngineer
      implements Developer, Designer {
      code() {
        console.log("Writing code");
      }
    
      design() {
        console.log("Designing UI");
      }
    }

    Why It Matters?

    Smaller, focused interfaces reduce unnecessary dependencies and make systems easier to evolve.

    Dependency Inversion Pricinple

    High-level business logic should depend on abstractions and not on concrete implementations.

    Bad Design

    class MySQLDatabase {
      save(data: string) {
        console.log("Saved to MySQL");
      }
    }
    
    class UserService {
      private db = new MySQLDatabase();
    
      createUser(name: string) {
        this.db.save(name);
      }
    }

    You can observe that UserService directly depends on MySQLDatabase which is bad. Also, switching to another service requires changing UserService.

    This can be made better in the following manner.

    Good Design

    interface Database {
      save(data: string): void;
    }
    
    class MySQLDatabase implements Database {
      save(data: string) {
        console.log("Saved to MySQL");
      }
    }
    
    class PostgresDatabase implements Database {
      save(data: string) {
        console.log("Saved to PostgreSQL");
      }
    }
    
    class UserService {
      constructor(private db: Database) {}
    
      createUser(name: string) {
        this.db.save(name);
      }
    }

    Look, how switching provider is made possible in the run time based on the requirement.

    const db = new PostgresDatabase();
    
    const userService = new UserService(db);
    
    userService.createUser("John");

    Why It Matters?

    Swapping implementations become easier. So is introducing mocks for unit testing. Also, dependency inversion can reduce coupling between components.

    Along with SOLID, you may have heard about KISS (Keep It Short and Simple) and YAGNI (You’re Not Gonna Need It) in Software engineering.

  • Week 41: My Job Applications: The Failure & The Fix

    Week: Oct 05 to Oct 10, 2026

    I wrote about my next career progression towards becoming an AI Engineer. Since I wanted to be part of AI Engineering roles, I prepared my resume and started applying for suitable positions.

    I almost spent a decade in my previous stint. So I know I cannot get the resume right the first time. Because, a lot has changed since then.

    Thought I spent a lot of time in coding & development, I spent considerable amount of time in the other areas — architecture & technical decisions, collaborations & leadership and in strategy and planning.

    After a week applying for 12 positions, I realized that companies choose to move forward with candidates whose experience align more closely than mine for the Product Manager roles.

    So, applying for a Product Manager role needs more credibility in my case. This in no way means that I’m a bad product manager or I don’t have the skills. Or at least that’s how I choose to see.

    So, what did I learn? Either I need more credibility or I need to look for engineering roles where I can add value with my existing full-stack experience. I chose to look for engineering positions that also demand AI skills.

    In addition, I also learnt that instead of describing the value of projects in plain text, I can also list the technologies used in the projects. Companies relate to the technologies used. At least the ATS (Applications Tracking System) do.

  • Companies Offering Remote Roles

    The following are the list of Product companies that look for remote workforce. I’ll keep adding to the list as and when I find such companies.

    1. https://www.atlassian.com/company/careers/all-jobs?team=Engineering&location=&search=
    2. https://www.deel.com/careers/

  • My Next Career Progression And Why?

    Most of my career, over the last 15 years, has been spent on software coding & implementation.

    To move up the career ladder, there are four areas that I need to consider:

    1. Coding & implementation
    2. Architecture & technical decisions
    3. Collaboration & leadership
    4. Strategy, planning & analysis

    My next career progression should not only involve coding & implementation but also technical decisions, leadership and strategy planning. This puts me in the Senior Product Engineering roles and I can then naturally progress in leadership directions — Engineering lead, Engineering manager & then to Head of Engineering roles.

    To make the next move more relevant and to stay ahead I must evolve in to AI frontier roles that involve the above areas. The AI frontier demands the knowledge of RAG and enterprise knowledge systems, Agentic AI and orchestration, AI evaluation and production engineering and Forward Deployed Engineering (FDE).

    The knowledge of the above systems would then allow me to look for Senior AI Product Engineer, Applied AI Engineer, AI Applications Engineer, and Forward Deployed Engineer roles in addition to the Senior Product Engineer roles.

  • [Project Management] What Is A Funnel?

    A funnel in project management is a framework used to track how user, customers and outcomes move through a series of stages towards a desired outcome.

    My friends and I are currently building an EMR (Electronic Medical Records) application for hospitals. Our goal is to get doctors to adopt to our product. In this case, a funnel may look like the following:

    How Does A Funnel Help Achieve Project Sucess?

    Funnels help project managers make decisions using measurable outcomes rather than assumptions.

    Conversion Rate=Users at next stageUsers at current stage×100\text{Conversion Rate} = \frac{\text{Users at next stage}}{\text{Users at current stage}} \times 100

    For example, 400 out of 600 doctors complete onboarding:

    400600×100=66.7%\frac{400}{600} \times 100 = 66.7\%

    Using the conversion rate, project managers can then make decisions to improve user and business outcomes.

  • Takedown In Muay Thai

    Takedowns are common in Muay Thai and is used to break your opponents’ confidence in the fight.

    In this video, Khamzat explains how to takedown in Muay Thai.

    Notice how he stands in Orthodox stance and moves using his left leg to close the distance. He keeps his head facing the opponent the entire time and not looking down.

    Once he closes the distance, he then uses head to lock the opponent’s shoulder blades, blocking his limbs to avoid punches. He, then, lifts and throws the opponent down.

    He also maintains the orthodox stance the entire time to not lose his stability.

  • Stepping Into Muay Thai: The Art Of Eight Limbs

    Muay Thai, originated from Thailand, is a descendant art of Muay Boran (means ancient boxing). Muay Boran represents traditional fighting systems while Muay Thai is a modern combat sport with standardized rules.

    Muay Thai was used in times of warfare especially when soldiers lose their weapons. Muay Thai, often referred as the art of eight limbs, mimics the weapons of the war. Hands become the sword (dagger), Elbows become the war hammers, Shins and Knees become the axe and the staff (a long cylindrical pole used for striking, blocking & sweeping)

    Why Did I Choose Muay Thai Training?

    1. This is by far the best accessible form of art in the place where I live. Had I been in the southern parts of Tamil Nadu, I would have chosen Adimuari or Kalari. From the stances of these arts, I’m starting to believe Muay Thai must have evolved from Adimuari.
    2. Muay Thai demands excellent cardio, explosiveness, balance, coordination, mobility and excellent core strength. Every sparring session can be a serious workout.
    3. Muay Thai begins with a big heart (not metaphorically but literally). Running twice every day is must. Longer runs in the morning and shorter in the evening.
    4. You can train without competing. Plenty train for fitness, skill and as a self defence art. You don’t need to fight professionally.
    5. Muay Thai forces you to learn to use your eight limbs in coordination.
  • GTM Strategy & GTM Engineering

    1 and 10 posts in LinkedIn would portray terms GTM strategy and/or GTM engineering. This post is my best effort to understand what GTM strategy & GTM engineering is.

    GTM stands for go-to-market. GTM strategy is all about finding the right customers, communicating your value, acquiring them efficiently and building a sustainable business be it products or services.

    “How is this different from traditional marketing?”, might you ask. Marketing is a component of GTM strategy.

    Let us understand with an example. Imagine you are starting an agency offering software development services.

    In traditional marketing way, you would create a website showcasing your services, improve SEO, publish blogs and create Google Ads targeting business.

    With GTM strategy, you would first answer questions like who your target audience is, your ideal customers, their problem, your value proposition, pricing, acquisition channels, sales process, delivery strategy, success metrics, etc.

    Answering the above questions would then help you determine what marketing campaigns to run and to whom.

    GTM engineering is the practice of using software engineering, automation, AI and data to help a business to acquire customers, increase sales and grow revenue.

  • What is A Cohort?

    Cohort is a way of grouping people, projects so one can manage, observe, compare their progress over time.

    Imagine this scenario — a SaaS application onboarding customers each month. In this case, a cohort can be customers signing up to the SaaS every month. That may mean 100 customers signing up in January, 150 customers joining in February and 200 customers signing up in March.

    You can then measure how each cohort performs. So, you can track retention, engagement, conversion and feedback, etc.

    Why Is Cohort Important In Project Management?

    Cohorts allow project managers to understand how specific groups perform overtime. Project managers can then measure progress, identify problems early, compare performance, improved decision making and evaluate improvements.

    You can see how cohorts can help improve retention in a SaaS using the chart above.