Skip to content

Migrations

Migrations require careful, systematic changes across a codebase. ralph’s iterative approach ensures consistent progress with verification at each step.

Migrate from one schema to another.

# Database Schema Migration
Migrate from legacy schema to new normalized schema.
## Schema Changes
### Users Table
Old:
```sql
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(255),
address VARCHAR(500),
city VARCHAR(100),
country VARCHAR(100)
);

New:

CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(255),
address_id INT REFERENCES addresses(id)
);
CREATE TABLE addresses (
id INT PRIMARY KEY,
street VARCHAR(500),
city VARCHAR(100),
country_id INT REFERENCES countries(id)
);
  1. Create new tables (migration file)
  2. Migrate data (migration file)
  3. Update application code to use new schema
  4. Update queries
  5. Drop old columns (final migration)
  • Update TypeScript types
  • Update ORM models
  • Update repository methods
  • Update API responses
  1. Create migration file: npm run db:migrate:create
  2. Run migration: npm run db:migrate
  3. Update affected code
  4. Run tests
  5. Commit with migration number
  • npm run db:migrate:status shows all applied
  • All tests pass
  • No references to old column names

When schema is fully migrated and all tests pass, output: COMPLETE

## TypeScript Upgrade
Upgrade TypeScript and fix all new errors.
### Setup
```toml
adapter = "claude"
maxIterations = 40
# Upgrade TypeScript to 5.x
Upgrade from TypeScript 4.x to 5.x and fix all type errors.
## Step 1: Upgrade
```bash
npm install typescript@5 --save-dev
// Old (might warn)
import { Type } from './types';
// New (explicit type import)
import type { Type } from './types';
// moduleResolution: "bundler" is new option
// May need to update tsconfig.json
  1. Run npm run typecheck to see errors
  2. Fix errors one file at a time
  3. Run typecheck again
  4. Commit when a batch of errors is fixed

May need to update:

  • target
  • module
  • moduleResolution
  • strict options

When npm run typecheck exits with 0, output: COMPLETE

## Node.js Version Upgrade
Upgrade Node.js version and fix compatibility issues.
### Prompt
```markdown
# Upgrade Node.js 18 to 20
Upgrade from Node.js 18 to Node.js 20 LTS.
## Changes to Address
### 1. Package.json
Update engines:
```json
{
"engines": {
"node": ">=20.0.0"
}
}

Node 20 has native fetch. Can remove:

  • node-fetch
  • cross-fetch
  • polyfills

Check for deprecated APIs:

  • url.parse()new URL()
  • querystringURLSearchParams
  1. Update .nvmrc to 20
  2. Update package.json engines
  3. Run npm install with Node 20
  4. Fix deprecation warnings
  5. Run tests
  6. Update CI config

Update GitHub Actions / other CI:

node-version: '20'

When all tests pass on Node.js 20, output: COMPLETE

## Framework Migration
Migrate from Express to Fastify (example).
### Prompt
```markdown
# Migrate Express to Fastify
Replace Express.js with Fastify for better performance.
## Conversion Patterns
### App Setup
```typescript
// Express
import express from 'express';
const app = express();
// Fastify
import Fastify from 'fastify';
const app = Fastify({ logger: true });
// Express
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id });
});
// Fastify
app.get('/users/:id', async (request, reply) => {
return { id: request.params.id };
});
// Express middleware
app.use(express.json());
app.use(cors());
// Fastify plugins
await app.register(fastifyCors);
// JSON parsing is automatic
  1. Install Fastify: npm install fastify @fastify/cors
  2. Create new app.ts with Fastify setup
  3. Migrate routes one by one
  4. Migrate middleware to plugins
  5. Update tests
  6. Remove Express: npm uninstall express
  1. Start with app.ts / main entry
  2. Migrate one route file at a time
  3. Run tests after each file
  4. Commit after each successful migration

When no Express imports remain and all tests pass, output: COMPLETE

## CSS Framework Migration
Migrate from one CSS approach to another.
### Prompt
```markdown
# Migrate CSS Modules to Tailwind
Replace CSS Modules with Tailwind CSS utility classes.
## Conversion Examples
### Basic Styling
```jsx
// Before (CSS Modules)
import styles from './Button.module.css';
<button className={styles.primary}>Click</button>
// .primary { background: blue; color: white; padding: 8px 16px; }
// After (Tailwind)
<button className="bg-blue-500 text-white px-4 py-2">Click</button>
// Before
<div className={`${styles.card} ${isActive ? styles.active : ''}`}>
// After
<div className={`p-4 rounded shadow ${isActive ? 'ring-2 ring-blue-500' : ''}`}>
  1. Ensure Tailwind is configured
  2. Pick a component
  3. Convert CSS classes to Tailwind utilities
  4. Remove CSS Module import
  5. Delete .module.css file
  6. Test visual appearance
  7. Commit
Terminal window
find src -name "*.module.css" | head -1

When no .module.css files remain in src/, output: COMPLETE

<Aside type="tip" title="Migration Testing">
For migrations, visual testing is important. Consider adding screenshot comparisons before and after.
</Aside>
## Tips for Migration Tasks
### 1. Establish Clear Conversion Rules
Tables work well:
```markdown
| Before | After |
|--------|-------|
| `oldFunction()` | `newFunction()` |

Specify what to migrate first:

## Migration Order
1. Core utilities (no dependencies)
2. Shared components
3. Feature modules
4. Entry points
## If Something Breaks
1. `git stash` current changes
2. Identify the breaking change
3. Create a fix or skip that file
4. Continue migration
## After Each File
- Build: `npm run build`
- Typecheck: `npm run typecheck`
- Test: `npm test`