TILs - Fueling Curiosity, One Insight at a Time

At Codemancers, we believe every day is an opportunity to grow. This section is where our team shares bite-sized discoveries, technical breakthroughs and fascinating nuggets of wisdom we've stumbled upon in our work.

Published
Author
user-image
Satya
the term Cannibalization in warehouse terms meaning taking components or parts from one unit (often damaged, unused, or scrapped) to use in repairing or completing another unit.
In simple terms we can understand it as refubrished items where later the warehouse can send that to a buyer and then the buyer decide which store to sell these items in a discounted price.

#warehouse #outbound
Published
Author
user-image
Sudeep
JavaScript Temporal — A Modern Approach to Date & Time

Today I explored the Temporal API in JavaScript — a long-awaited, modern alternative to the built-in Date object.
The traditional Date API is known for its limitations: it’s mutable, difficult to work with across time zones, and error-prone when performing date arithmetic. Temporal addresses these issues with a clean, consistent, and powerful API.

Key Advantages of Temporal
Immutable: All Temporal objects are immutable, avoiding side effects
Time zone-aware: Native support via ZonedDateTime
Consistent parsing & formatting
Clear duration handling with Temporal.Duration
More intuitive syntax — no more 0-based months
Practical Examples

JavaScript

// Get current date-time
const now = Temporal.Now.plainDateTimeISO();
console.log(now.toLocaleString()); // "6/18/2025, 6:01:52 PM"

// Time zone conversion
const nyMeeting = Temporal.ZonedDateTime.from('2025-06-18T10:00[America/New_York]');
const kolkataTime = nyMeeting.withTimeZone('Asia/Kolkata');
console.log(kolkataTime.toLocaleString()); // "6/18/2025, 7:30:00 PM GMT+5:30"


Working with Durations

JavaScript

const start = Temporal.PlainDate.from('2025-01-01');
const end = Temporal.PlainDate.from('2025-06-18');
const diff = start.until(end);
console.log(diff.toLocaleString()); // "168 days"


Why This Matters ?
Whether you're building scheduling systems, handling international time zones, or performing complex date calculations — the Temporal API offers accuracy, clarity, and reliability that the current Date API lacks.

#CCT1JMA0Z
Published
Author
user-image
Nitturu
The difference between Active Model association call, joins and includes. Consider two tables: order_requests and orders, where each order_request has many orders.

1. order_request.orders
Purpose: You’re accessing the associated orders from a single order_request object.
Behavior: This will trigger a separate SQL query unless the association was already loaded (using includes).

Code

SELECT "orders".* FROM "orders" WHERE "orders"."order_request_id" = 123;


• Use Case: When you’re working with one order_request and want to fetch its orders.

2. order_requests.joins(:orders)
Purpose: Adds an INNER JOIN in the SQL between order_requests and orders.
Behavior: Doesn't load orders into memory, just uses them for filtering or sorting in SQL.

Code

SELECT "order_requests".* 
FROM "order_requests"
INNER JOIN "orders" ON "orders"."order_request_id" = "order_requests"."id";


• Use Case: When you want to query order_requests based on conditions in orders (e.g., where(orders: { status: 'active' })), but don’t need to access orders in Ruby.

3. order_requests.includes(:orders)
Purpose: Performs eager loading via a LEFT OUTER JOIN + separate query, or just a separate query depending on ActiveRecord's optimization.
Behavior: Loads orders for each order_request to prevent N+1 queries when looping.

Code

SELECT "order_requests".* FROM "order_requests" WHERE ...
SELECT "orders".* FROM "orders" WHERE "order_request_id" IN (1, 2, 3, ...)


• Use Case: When you plan to access order_request.orders for many records in a loop and want to avoid repeated SQL calls (N+1 issue).

#Rails
Published
Author
user-image
Sudeep
How Decorators Work in NestJS

Decorators in NestJS are a powerful way to attach metadata to routes, classes, or parameters. Today, I implemented a custom @Roles() decorator to control access to certain routes based on user roles.

Example:

Custom Decorator: @Roles()

TypeScript

// roles.decorator.ts
import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);


This attaches metadata like roles = ['Admin'] to the route handler.

Guard to Read Metadata

TypeScript

// roles.guard.ts
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.get<string[]>(
      'roles',
      context.getHandler()
    );

    const request = context.switchToHttp().getRequest();
    const user = request.user;

    return requiredRoles?.includes(user?.role); // Check if user has the role
  }
}


Controller Usage

TypeScript

@UseGuards(RolesGuard)
@Roles('Admin')
@Patch(':id')
updateOrg() {
  // This route is accessible only to users with the 'Admin' role
}


Under the hood, decorators use Reflect.defineMetadata to attach metadata, and NestJS’s Reflector service helps retrieve that metadata in guards or interceptors.

Takeaway: Custom decorators make your code cleaner, declarative, and easier to manage — especially when dealing with role-based access in multi-user systems.

#typescript #NestJs
Published
Author
user-image
Puneeth
Using emit in NestJS

In NestJS, event-based communication can be implemented using @nestjs/event-emitter package, which is built on top of eventemitter2 . It's particularly useful for decoupling the parts of our application — for example, sending notifications, logging, or triggering async jobs after certain actions.

How to use it?

Install the necessary package:

Code

npm install --save @nestjs/event-emitter


Register the module in the app:

Code

// app.module.ts
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot(),
  ],
})
export class AppModule {}


Emit an event from anywhere in the app:

Code

// user.service.ts
import { EventEmitter2 } from '@nestjs/event-emitter';

@Injectable()
export class UserService {
  constructor(private eventEmitter: EventEmitter2) {}

  async createUser(userDto: CreateUserDto) {
    const user = await this.userRepository.save(userDto);
    
    this.eventEmitter.emit('user.created', user); // 🔥

    return user;
  }
}


Handle the event using a listener:

Code

// user.listener.ts
import { OnEvent } from '@nestjs/event-emitter';

@Injectable()
export class UserListener {
  @OnEvent('user.created')
  handleUserCreatedEvent(payload: any) {
    console.log('User created!', payload);
    // Trigger welcome email, analytics, etc.
  }
}


Why use emits?

Decouples the core logic from side-effects
Makes it easier to add/remove behaviours like notifications, logging
Encourages modular architecture

#CCT1JMA0Z #nestJs #event_based_communication
Published
Author
user-image
Sudeep
Difference Between jest.fn() and jest.spyOn() in Jest

🧪 While writing tests in Jest, I came across two commonly used utilities: jest.fn() and jest.spyOn(). They may seem similar, but they serve different purposes:

🔹 jest.fn()
• Creates a new mock function from scratch
• Ideal when you want to replace a function with a mock implementation entirely
• Commonly used to inject mocked dependencies in unit tests

Code

const mockFn = jest.fn();
mockFn('arg'); 
expect(mockFn).toHaveBeenCalledWith('arg');


🔹 jest.spyOn()
• Spies on an existing method of an object
• Allows you to observe calls to the method or mock its implementation, while retaining the original object structure

Code

const obj = {
  greet: () => 'Hello',
};

const spy = jest.spyOn(obj, 'greet');
obj.greet();
expect(spy).toHaveBeenCalled();


👉 Use jest.fn() when creating mocks from scratch.
👉 Use jest.spyOn() to observe or override existing methods.

#jest #CCT1JMA0Z #testing
Published
Author
user-image
Puneeth
Recover Lost Data in PostgreSQL

Most SQL databases, like PostgreSQL, let us restore the database to a specific point in time — this is called Point-In-Time Recovery (PITR). PostgreSQL makes this possible using something called the Write-Ahead Log (WAL).

The WAL keeps a log of every change made to the database, like adding, updating, or deleting the data. Each of these log has a unique ID called as Log Sequence Number (LSN). This allows PostgreSQL to rebuild the database exactly as it was at any moment in the past.

However, PostgreSQL doesn’t keep these logs forever. A background process automatically removes old WAL files when they’re no longer needed to save space.

#postgreSQL #databases
Published
Author
user-image
Sudeep
How to Revoke (Undo) a Git Rebase

If you’ve run a git rebase and need to undo it due to issues, here’s a simple way to revert back:

1.Check your reflog to find the commit before rebase started:

Code

git reflog


Look for the commit hash just before the rebase (usually marked with rebase started).

2.Reset your branch back to that commit:

Code

git reset --hard <commit-hash>


This will reset your branch to the exact state before the rebase.

Important:
• Use git reset --hard with caution, as it will discard any uncommitted changes.
#Git
Published
Author
user-image
Sudeep
React Query

It simplifies data fetching, caching, syncing, and updating — without manually managing loading or error states.
Here’s a small snippet I worked on today:


JavaScript

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

const fetchOrganisations = async () => {
  const { data } = await axios.get('/api/organisations');
  return data;
};

const Users = () => {
  const { data, isLoading, error } = useQuery(['organisations'], fetchOrganisations);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error fetching organisations</p>;

  return (
    <ul>
      {data.map(organisation => (
        <li key={organisation.id}>{organisation.name}</li>
      ))}
    </ul>
  );
};


💡 What I love:
• Built-in caching
• Automatic background refetching
• Easy-to-use API with powerful features
#CCT1JMA0Z #FrontendDevelopment
Published
Author
user-image
Sudeep
Typescript as const turns everything into readonly.


TypeScript

const user = {
  role: 'admin',
} as const;

user.role = 'editor'; // ❌ Error: Cannot assign to 'role' because it is a read-only property.


💡 as const is great for making values literal and immutable — useful in Redux, Enums, etc.

#Typescript #CCT1JMA0Z
Published
Author
user-image
Sudeep
JavaScript: Object.groupBy()

Grouping data used to be messy — relying on Array.reduce() with verbose logic. But JavaScript's new Object.groupBy() method has made things incredibly elegant and easy!

With just one line, you can group array items based on any property.
It’s clean, readable, and production-friendly.

📌 Example:


JavaScript

const products = [
  { name: "T-shirt", category: "clothes", price: 50 },
  { name: "Apple", category: "food", price: 5 },
  { name: "Shoes", category: "clothes", price: 35 },
  { name: "Orange", category: "food", price: 7.5 },
  { name: "Blueberry", category: "food", price: 4.5 }
];

const grouped = Object.groupBy(products, product => product.category);

console.log(grouped);


💡 Output:


JavaScript

{
  clothes: [
    { name: "T-shirt", category: "clothes", price: 50 },
    { name: "Shoes", category: "clothes", price: 35 }
  ],
  food: [
    { name: "Apple", category: "food", price: 5 },
    { name: "Orange", category: "food", price: 7.5 },
    { name: "Blueberry", category: "food", price: 4.5 }
  ]
}


Cleaner. Less boilerplate. Much easier to read.

#CCT1JMA0Z #WebDevelopment
Published
Author
user-image
Vaibhav Yadav
Senior System Analyst
Using Makefile for tedious commands

A Makefile can be used to automate a commands, simplifying the execution process. Here’s a concise example:


Code

.PHONY: run-script

# Target to run a long command
run-script:
\t@echo "Running a long command..."
\tsleep 5  # Simulate a long-running command
\t@echo "Command completed."


Running the Makefile
1. Create a Makefile: Save the above content as Makefile in your project directory.
2. Run Make: In your terminal, navigate to the project directory and execute:

Code

make run-script


Benefits
• Simplicity: Easily run a long command without remembering the syntax.
• Automation: Reduces manual effort and potential errors.
#cli #automation #makefile #commands
Published
Author
user-image
Sudeep
💡 Why is [] == ![] true in JavaScript?

It all comes down to type coercion and how JavaScript evaluates expressions using the == (abstract equality) operator.

Here’s the breakdown:
![] evaluates to false because an empty array is truthy, and the ! operator negates it.
So the expression becomes: [] == false
When comparing an object (like[]) to a boolean with==, JavaScript converts both sides to numbers:
+[] → 0
+false → 0
So:

JavaScript

[] == ![]  
=> [] == false  
=> +[] == +false  
=> 0 == 0  
=> true


Hence, [] == ![] evaluates to true.

#CCT1JMA0Z
Published
Author
user-image
Adithya Hebbar
System Analyst
How Dependency Injection Works in NestJS

NestJS uses Dependency Injection (DI) to manage the creation and lifecycle of classes like services, repositories, and providers. It leverages TypeScript's metadata to resolve dependencies automatically.

🚀 How It Works:

Declare Providers: Services and other classes are marked with @Injectable() to make them available for dependency injection. They are then registered as providers in a module.

TypeScript

// user.service.ts
@Injectable()
export class UserService {
  getUsers() {
    return ['Alice', 'Bob'];
  }
}


Register Providers in a Module

TypeScript

// user.module.ts
@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}


Use the Service via Constructor Injection

TypeScript

// user.controller.ts
@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  findAll() {
    return this.userService.getUsers();
  }
}


NestJS reads the constructor types and injects the required instances for you. No manual instantiation needed!

Benefits:
• Decouples components
• Simplifies testing with mocks
• Promotes cleaner, modular code

#nestjs #dependencyinjection #typescript
Published
Author
user-image
Sudeep
How to Revoke and Amend the Most Recent Git Commit Message.
To undo the most recent commit, unstage the changes, and update the commit message, follow these steps:

1. Revoke the latest commit and unstage the changes.
git reset HEAD~1

2. Stage the changes again.
git add .

3. Create a new commit with the updated message
git commit -m "New commit message"
(If you just want to change the previous commit message) - git commit --amend

4. Force-push the new commit to the remote repository
git push origin <branch-name> --force

⚠️ Use --force cautiously, especially on shared branches, as it rewrites history.
Published
Author
user-image
Nived
pgvector provides native support for vector similarity search in PostgreSQL. It supports three types of distance metrics, each useful depending on the use case:
<=> Cosine distance – Measures the angle between two vectors (ignores magnitude). Great for comparing meaning in text (e.g., NLP). Smaller angle = more similar.
<#> L2 (Euclidean distance) – Measures the straight-line distance between two vectors. Takes both direction and size into account. Good when actual value differences matter (like in image or audio data).
<-> Inner product – Measures how much two vectors point in the same direction and how large they are. If vectors are normalized (length = 1), it works like cosine similarity. Great for ranking similarity when vectors are preprocessed.

#pgvector #PostgreSQL #VectorSearch #Embeddings
Published
Author
user-image
Puneeth
ClickHouse DB

It is a column-oriented database management system designed for online analytical processing (OLAP). It's optimised for real-time analytics on large volumes of data and is known for being fast, highly scalable, and efficient for read-heavy workloads like metrics, logs, events, and other analytical data.

Key features are -
1. Columnar storage : Stores data by columns instead of rows, enabling efficient compression and faster reads.
2. Works super fast : Designed to process billions of rows per second per server.
3. SQL-compatible.
4. Materialized views : For real-time aggregation and data transformation.
#databases #click_house_db #analytics
Published
Author
user-image
Puneeth
Validating date and time field in Rails

validates_timeliness gem helps us to check if a date or time field is valid and meets certain conditions — like being in the past, in the future, or within a specific range. It can do following things.
1. Check if a date is valid (e.g., "2025-02-30" is not a valid date).
2. Make sure a date is before or after a certain time as needed.
3. Restrict a field to only accept dates, times or datetimes.
4. Works well with user input in different formats.
For example :

Ruby

class Event < ApplicationRecord
  validates_timeliness :start_time, on_or_after: :now, type: :datetime
end


This makes sure start_time is not in the past.

#CU6U0R822 #date_time_validation
Published
Author
user-image
Mohammad
friendly_id is a Rails gem that lets you use secure, human-readable slugs instead of record IDs in URLs.
https://github.com/norman/friendly_id
it updates the url
from this :

Code

https://localhost:3000/employer/job_posts/2/job_applications/new


to this:

Code

https://localhost:3000/employer/job_posts/frontend-developer-37b70ea4-761e-4369-832e-f5b373f7f00b/job_applications/new


#CU6U0R822
Published
Author
user-image
Syed
rails_representation_url in Rails is used to generate a URL for a variant of an Active Storage image, not the original blob. It's especially useful when we want to apply transformations like resizing or converting image formats on-the-fly.


Ruby

rails_representation_url(
  image.variant(resize_to_limit: [300, 300], saver: { quality: 80 }, format: :webp).processed,
  only_path: true
)


image.variant(...) creates a variant of the image, resizing it to a maximum of 300x300 pixels, converting it to WebP format, and reducing its quality for optimization.
.processed ensures the variant is actually processed before generating the URL.
rails_representation_url(...) then generates the URL for this transformed version.
only_path: true returns a relative path (instead of a full URL), which is often preferred in views or frontend routing.
This is a great way to deliver performance-optimized images for the UI

#rubyonrails

Showing page 3 of 42

Your competitors are already using AI.
The question is how fast you want to unlock the value.

Don't know where to start?

AI is everywhere but it's unclear which investments will actually move your metrics and which are expensive experiments.

Your data isn't ready

Most AI projects fail at the data layer. Pipelines, quality, access all need work before LLMs can deliver value.

Internal teams are stretched

Your engineers are shipping product. They don't have capacity to also become AI specialists with production-grade experience.

Legacy systems block everything

Aging, undocumented codebases make AI integration slow, risky, and expensive. They need to move first.

Don't worry. We've got you covered.

Start with the audit.