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
Syed
The Problem: When comparing images for UI testing, we needed to implement a fuzz factor to ignore small colour differences (like anti-aliasing, compression artifacts, or minor rendering variations). This is crucial for UI screenshots where a 1-2 pixel difference shouldn't count as a "failure."

Command Line approach

Code

# This works but is fragile
magick compare -metric AE -fuzz 10% image1.png image2.png NULL: 2>&1

# Problems:
# - Shell command parsing issues
# - Error handling is difficult
# - Output parsing is brittle
# - Cross-platform compatibility issues
# - Hard to debug when things go wrong


The Mini Magick Solution

Code

# Step 1: Create difference image
difference_image = first_image.composite(second_image) do |c|
  c.compose "difference"
end

# Step 2: Apply fuzz factor using threshold
thresholded_diff = difference_image.dup
thresholded_diff.combine_options do |c|
  c.normalize
  c.threshold "10%"
# This acts as our fuzz factor!
end

# Step 3: Get statistics
mean_value = thresholded_diff.identify do |c|
  c.format "%[fx:mean]"
end

# Step 4: Convert to percentage
percentage = mean_value.to_f * 100


Key Insight: Fuzz Factor = Threshold
- In ImageMagick: fuzz 10% tells it to ignore differences below 10%
- In MiniMagick: threshold10% does the same thing by setting pixels below 10% to black

#ruby #image
Published
Author
user-image
Syed
* The Problem:* I had an existing Elixir app with a users table that used password_digest field, but Devise expects encrypted_password by default.

Devise's Default Password Field:

Code

# Devise expects this by default:
class User < ApplicationRecord
  devise :database_authenticatable
  # Uses 'encrypted_password' column automatically
end


Our Existing Schema:

Code

# Uses password_digest
create_table :users do |t|
  t.string :password_digest, null: false  # ← Different field name!
  # ... other fields
end


The Override Solution:

Code

# Devise calls: user.encrypted_password
# Our override returns: user.password_digest

class User < ApplicationRecord
  devise :database_authenticatable, :registerable, :validatable

  # Tell Devise to use our existing password_digest field
  def self.encrypted_password_column
    :password_digest
  end

  # Override the getter method
  def encrypted_password
    read_attribute(:password_digest)
  end

  # Override the setter method  
  def encrypted_password=(value)
    self.password_digest = value
  end
end


So we can simply override Devise's password field by:
1. Telling Devise which column to use (encrypted_password_column)
2. Creating getter/setter bridges (encrypted_password methods)
3. Using read_attribute to avoid method conflicts
#devise #auth
Published
Author
user-image
Syed
What does model: resource actually do in form_with?

model: resource is the bridge between our form and the data object. It makes forms smart - they remember values, show errors, and handle the complex Rails form lifecycle automatically.

Example:

Code

<%= form_with model: resource, as: resource_name, url: session_path(resource_name), local: true, class: "space-y-6" do |f| %>


model: resource tells Rails:
• Which object to bind the form to
• Where to get field values from
• Where to send validation errors to
• What HTTP method to use (POST for new, PATCH for existing)
In Devise Context:
resource is a Devise helper that returns:
• New User object (for signup) - User.new
• New User object (for signin) - User.new (usually empty, not pre-populated)
Without model: resource:
• Form fields are always empty
• No automatic error handling
• Manual parameter naming required
• No automatic HTTP method detection
#CU6U0R822 #devise
Published
Author
user-image
Satya
To understand network sockets locally, you can try this simple demo with two terminal tabs:
1. In the first tab run ns -l 1234 : This starts a small server process that listens for TCP connections on your computer’s address (localhost / 127.0.0.1) at port 1234.
2. In the second tab run ns localhost 1234 : This connects a client to the server on 127.0.0.1:1234 , creating a TCP connection between the two processes.
Now type text in one terminal and press Enter you’ll see the same text appear in the other terminal and vice-versa. 🚀

#sockets
Published
Author
user-image
Ashwani Kumar Jha
Senior System Analyst
Filtering API logs with path params in OpenSearch

When querying logs in OpenSearch Dashboards, paths with dynamic segments (like IDs) often don’t match with the usual search bar syntax because the field is mapped as text instead of keyword.

Problem:
• Queries like

Code

json.req.url: "/api/bankAccounts/*/debit"


return no results.
.keyword may not exist (json.req.url.keyword) if the field wasn’t mapped that way at ingestion.
Solution:
Use Query DSL with a wildcard or regexp query.

Wildcard query (matches any value in the middle):

Code

{
  "query": {
    "wildcard": {
      "json.req.url": {
        "value": "/api/bankAccounts*/debit"
      }
    }
  }
}


Regex query (restricts the middle part to numbers):

Code

{
  "query": {
    "regexp": {
      "json.req.url": "/api/bankAccounts/[0-9]+/debit"
    }
  }
}


#opensearch #logs
Published
Author
user-image
Mohammad
You can mark methods as deprecated in Rails using ActiveSupport::Deprecation. This warns developers that a method will be removed in future versions.


Code

class User < ApplicationRecord
  def full_name
    "#{first_name} #{last_name}"
  end

  # Mark full_name as deprecated
  deprecate :full_name, deprecator: ActiveSupport::Deprecation.new("2.0", "MyApp")
end



Code

DEPRECATION WARNING: full_name is deprecated and will be removed from MyApp 2.0


💡 Might be especially useful in larger codebases, where many developers might be using the same method and you want to safely signal that it will be removed without breaking things immediately.
#Rails
Published
Author
user-image
Nived
In Prisma, there’s a big difference between directly setting a foreign key and using connect when creating related records.

Code

// ❌ Directly setting the foreign key
users: {
  create: {
    userId: testUser.id,
  },
}

// ✅ Using relation API
users: {
  create: {
    user: {
      connect: { id: testUser.id },
    },
  },
}


Direct assignment just writes the raw foreign key value — Prisma doesn’t check if the user actually exists.
connect uses Prisma’s relation API, validates that the record exists, and safely links them.

#prisma
Published
Author
user-image
Ashwani Kumar Jha
Senior System Analyst
Nx has a built-in command to remove libraries

Nx provides the @nx/workspace:remove generator that can remove a library from our workspace.

The command:

Code

npx nx g @nx/workspace:remove <library-name>


What it does automatically:
• Deletes the library folder and all its files
• Removes the project from nx.json and workspace configuration
• Checks for dependencies and warns if other projects still use it
We can use --forceRemove flag if we want to remove a library even when other projects depend on it (though this can break the build).
#nx #monorepo
Published
Author
user-image
Nived
WITH (NOLOCK) is often used to speed up queries by avoiding shared locks, which means the query won’t block other reads or writes. This can improve performance on busy systems, but it comes at the cost of data accuracy.

When using NOLOCK, SQL Server may:
• Read uncommitted (dirty) data that could later be rolled back.
• Return missing or duplicate rows due to page splits and concurrent writes.
• Show inconsistent values within the same row if columns are updated mid-read.
In short: NOLOCK trades reliability for speed. It’s fine for dashboards, reports, or monitoring where approximate numbers are acceptable, but it should be avoided for financial or critical business logic where accuracy is essential.

#sql
Published
Author
user-image
Sudeep
Prisma --create-only

npx prisma migrate dev --create-only --name <migration_name>

Creates a migration file with the SQL changes but does not apply them to the database.

Why this is useful:

Safe inspection – lets you review the generated SQL before running it, especially helpful for destructive operations like drops or PK changes.

Manual adjustments – you can tweak the SQL (e.g., add a USING clause for type casting or backfill data before dropping a column).

Separation of responsibilities – you can generate migrations while DBAs/ops review and apply them in controlled environments.

Key takeaway:

👉 --create-only is like a dry run for migration generation – you get the recipe, but the dish isn't cooked yet 🍳.

#postgres
Published
Author
user-image
Mohammad
Rails has a built-in way to reduce repetition in associations—with_options.
When multiple has_many relationships share the same option (like dependent: :destroy), repeating it clutters your model:


Ruby

class Account < ApplicationRecord
  has_many :customers, dependent: :destroy
  has_many :products,  dependent: :destroy
  has_many :invoices,  dependent: :destroy
  has_many :expenses,  dependent: :destroy
end


Using with_options, you can group them under one block:


Ruby

class Account < ApplicationRecord
  with_options dependent: :destroy do
    has_many :customers
    has_many :products
    has_many :invoices
    has_many :expenses
  end
end


This makes the intent clearer—all these associations share the same rule.
It's easier to read, less error-prone, and keeps your model DRY
#Rails
Published
Author
user-image
Ashwani Kumar Jha
Senior System Analyst
Next.js Typed Routes

Next.js now provides TypeScript support for route parameters and navigation, helping catch routing errors at compile time rather than runtime.

Next.js automatically generates route types based on our file structure in the app directory.

For example, if we have:

TypeScript

app/
  users/
    [id]/
      page.tsx
  posts/
    [slug]/
      page.tsx


The generated types will understand routes like /users/123 and /posts/my-post-slug.


TypeScript

import { useRouter } from 'next/navigation'
import Link from 'next/link'

// TypeScript knows about our routes
const router = useRouter()
router.push('/users/123') // ✅ Valid
router.push('/invalid-route') // ❌ TypeScript error

// Link component is also typed
<Link href="/posts/my-slug">My Post</Link> // ✅ Valid
<Link href="/wrong-path">Invalid</Link> // ❌ TypeScript error


#nextjs #typescript
Published
Author
user-image
Adithya Hebbar
System Analyst
How LLM's temperature affects AI output:

LLM models use a parameter called temperature to control randomness in generated responses.
temperature: 0 → deterministic output (same input = same output)
temperature: 1 → default setting, balanced creativity
temperature > 1 → more random, creative, but less reliable

Tip: Use lower temperatures when you need reliable, consistent responses, and higher temperatures for creative or exploratory tasks.
#llm
Published
Author
user-image
Mohammad
Traits in FactoryBot allow you to define reusable pieces of attributes that can be mixed into factories to create variations of objects without duplicating code.


Code

FactoryBot.define do
  factory :user do
    name { "John Doe" }

    trait :admin do
      role { "admin" }
    end
  end
end

create(:user, :admin)


Here, :admin is a trait that overrides or adds attributes (role: "admin").
You can pass traits to create, build, or attributes_for to easily generate variations.
#CU6U0R822 #RSpec
Published
Author
user-image
Swasthik
Boost Query Performance with Prisma's Rust-free Engine(v6.7.0+)

Why?
• Quick Setup
• Faster queries
• 85–90% bundle size reduce
• Smoother & Better DX
Setup Steps :

1. Update Your schema.prisma

Code

generator client {
  provider        = "prisma-client-js" // or `prisma-client`
  previewFeatures = ["queryCompiler", "driverAdapters"]
  output          = "../generated/prisma"
}


2. Re-Generate Prisma Client

Code

npx prisma generate


3. Install Driver Adapter
• For Postgres: npm install @prisma/adapter-pg
• For other DBs: https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/no-rust-engine#3-install-the-driver-adapter|Prisma Adapter Docs
4. Instantiate Prisma Client
For Postgres:

Code

import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from './generated/prisma'

const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
const prisma = new PrismaClient({ adapter })


For other DBs: https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/no-rust-engine#4-instantiate-prisma-client|Prisma Client Docs
5. All done!🎉 Now your can query as usual.

🔗 https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/no-rust-engine|Official Rust-free Prisma Docs
Published
Author
user-image
Sudeep
Picture-in-Picture (PiP) API – Enabling Floating Video Playback

The Picture-in-Picture (PiP) API enables developers to present an HTML <video> element in a small, floating, always-on-top window. This allows users to continue watching a video while interacting with other applications or browser tabs.

How to use it (basic example):

JavaScript

html

<video id="myVideo" src="video.mp4" controls></video>
<button id="pipButton">Enter PiP</button>



JavaScript

js

const video = document.getElementById('myVideo');
const button = document.getElementById('pipButton');

button.addEventListener('click', async () => {
  try {
    if (document.pictureInPictureElement) {
      await document.exitPictureInPicture();
    } else {
      await video.requestPictureInPicture();
    }
  } catch (err) {
    console.error(`Failed to toggle PiP: ${err}`);
  }
});


Key Concepts
video.requestPictureInPicture(): Initiates PiP mode for the video element.
document.exitPictureInPicture() : Exits PiP mode.
document.pictureInPictureElement : Returns the element currently in PiP, or null.
• Associated Events:
enterpictureinpicture
leavepictureinpicture

JavaScript

video.addEventListener('enterpictureinpicture', () => {
  console.log('Video entered PiP mode');
});

video.addEventListener('leavepictureinpicture', () => {
  console.log('Video left PiP mode');
});


⚠️ Limitations
• Only applicable to native <video> elements.
• Most browsers require the video to be playing before entering PiP.
• Must be triggered through a user gesture (e.g., a click).
• Safari has limited support and relies on its own implementation.
🌐 Browser Support
• Chrome
• Edge
• Opera
• Firefox (with some restrictions)
#CCT1JMA0Z
Published
Author
user-image
Sudeep
File Preview in React — Beyond Just Images
Building a file preview system in React can surface several helpful patterns — especially when working with images, PDFs, media, and plain text files.

• You can preview any local file before upload using:

JavaScript

URL.createObjectURL(file)


It works seamlessly with:
• Images
• PDFs
• Audio files
• Videos
• Plain text
Tip: Always call URL.revokeObjectURL() when the preview is no longer needed to prevent memory leaks.

🔄 Handling Local and Server Files Together
To support previews for both uploaded and already-stored files, use a union type:

JavaScript

// Local preview
{ isLocal: true, file: File }

// Server-hosted file
{ url: '/api/files/:id', name: string, type: string }


Then render conditionally based on file.type. Rendering Previews Based on File Type
<img> → for images
<iframe> → for PDFs or text files
<audio> / <video> → for media files
#CCT1JMA0Z #react
Published
Author
user-image
Nitturu
📌 Using Alpine.js in Rails to Toggle Content Efficiently

You can use Alpine.js in a Rails app to handle simple UI interactions like showing, hiding, or toggling content — with zero overhead and great maintainability.

🧠 How it works:
• Alpine adds lightweight reactivity directly in your HTML using attributes like x-data, @click, and x-show.
• Clicking a button updates the type (or any reactive) value.
• Alpine automatically re-evaluates all x-show (and related) bindings when that reactive value changes.
• It then updates the UI by toggling styles like display: none, not by re-rendering or manipulating the DOM.
• On clicking the "Urgent" button, Alpine applies display: none to the normal_partial and removes it from urgent_partial, effectively toggling visibility between the two.
💡 Example in Rails ERB:

Code

<div x-data="{ type: 'normal' }">
  <button @click="type = 'normal'">Normal</button>
  <button @click="type = 'urgent'">Urgent</button>

  <div x-show="type === 'normal'">
    <%= render "normal_partial" %>
  </div>

  <div x-show="type === 'urgent'">
    <%= render "urgent_partial" %>
  </div>
</div>


• Both partials are rendered server-side on initial load
• Alpine just toggles their visibility using CSS (e.g., display: none), it wont manipulate DOM.
• No data loss or performance bottleneck — ideal for UI tab switching or inline modals
Why it's great:
No page reloads or re-renders
• No JavaScript DOM manipulation — just CSS toggling
• Preserves state and DOM structure
• Ideal for tabs, modals, section toggles, and lightweight UI
#Rails #Alphine.js
Published
Author
user-image
Sudeep
Creating Google Calendar Events with NestJS

Integrating Google Calendar event creation in a NestJS backend can be done seamlessly using the googleapis package.
Key Steps:
• Set up OAuth2 with access and refresh tokens.
• Use calendar.events.insert() to create events.
• Always include the timeZone field to ensure accurate scheduling.
Sample code:

JavaScript

const event = {
  summary: 'Team Sync',
  start: { dateTime: '2025-06-26T10:00:00+05:30', timeZone: 'Asia/Kolkata' },
  end: { dateTime: '2025-06-26T11:00:00+05:30', timeZone: 'Asia/Kolkata' },
};

await calendar.events.insert({
  calendarId: 'primary',
  requestBody: event,
});


Common Pitfalls:
• Incorrect scopes → leads to permission denied errors.
• Missing timeZone → causes unexpected event timings.
• Expired tokens → results in 401 Unauthorized errors.
#NestJS
Published
Author
user-image
Sudeep
Understanding ExecutionContext in NestJS Guards

Today I learned how ExecutionContext works in NestJS — it's a powerful tool for accessing low-level request details within Guards, Interceptors, and Custom Decorators.
While building a custom AuthGuard, I used ExecutionContext to extract the request object and retrieve the authenticated user like so:


Code

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const user = request.user;

    return !!user; // or apply custom authorization logic
  }
}


Why It Matters:
ExecutionContext wraps the current request lifecycle and gives you flexible access to request-specific information.
• You can switch between different transport layers (HTTP, RPC, WebSockets) using methods like switchToHttp(), switchToRpc(), etc.
• It's essential for building dynamic and context-aware logic in guards, interceptors, and decorators.
Pro Tip:
Use context.getClass() and context.getHandler() to access metadata about the controller and handler being executed — especially useful for implementing role-based access control or custom permission systems.

#CCT1JMA0Z #NestJS

Showing page 2 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.