Our review
Automates the migration of TrustOn inspection checklist items and creation of WorkOrderRouting records when a new checklist version is released.
Strengths
- Provides both single-order and batch migration modes with dry-run support.
- Includes multiple script types (TypeScript, Python, SQL) for flexibility.
- Handles complex logic like splitting historical checklist items and preserving deleted ones.
- Automates required WorkOrderRouting creation to prevent 404 errors.
Limitations
- Requires manual selection of the correct checklist bundle before running.
- Migration scripts assume a specific database schema and may need adaptation.
- No built-in rollback mechanism beyond preserving deleted items.
Use when a new version of the TrustOn checklist is released and you need to update existing inspection orders and routing.
Do not use for one-off manual corrections to individual check items; prefer direct database edits or a custom API call instead.
Security analysis
CautionWhile the skill describes legitimate database migration operations, it involves powerful actions (batch updates, routing creation) with potential for destructive impact if used incorrectly. It does not contain obfuscated payloads or data exfiltration, but the risk of unintended data manipulation warrants caution.
- •The skill instructs executing database migration scripts and HTTP endpoints that directly modify production data. Improper use could lead to data loss or corruption.
- •No explicit validation of checklist bundle integrity before applying changes; a tampered bundle could inject malicious itemSpec data.
Examples
Run a dry-run migration of check items for order 12345 using the Centromash v4.9.7 full-from-xlsx checklist.Migrate all orders to the new Centromash checklist v4.9.7 full-from-xlsx, confirm the migration, and create routing for each order.Create missing WorkOrderRouting records for order 67890 using the TypeScript script create_routing_for_order.ts.name: truston-checklist-migration description: Migrate TrustOn inspection checklist items to a new version in the database
TrustOn Checklist Migration Skill
Automates upgrading CheckItem.itemSpec and creating WorkOrderRouting in the TrustOn database when checklist versions are released (e.g., v4.8 → v4.9.2).
When to use
- New checklist version released (v4.9.2, Centromash v4.9.2, v4.10, etc.)
- CheckItem specs need updating across all inspection orders
- Post ordering, items, or metadata has changed
- Need to add new check items or remove deprecated ones
- User requests to apply new checklist to specific vehicle/order
Problem
When checklist versions are released:
- The database contains thousands of CheckItem records with old specs
- Orders may be missing WorkOrderRouting records (causing 404 errors on
/orders/{orderId}/routingendpoint) - Manual updates are error-prone and time-consuming
Solution
This skill provides:
CheckItem Migration:
- TypeScript Script:
scripts/migrate_single_order_checklist.tsfor single order migration (RECOMMENDED) - HTTP Endpoint:
POST /migrate/checkitems-v{VERSION}for batch/single order migration - Query params:
?orderId=<id>(single),?dryRun=true(test),?confirm=true(production) - Safe operations: Preserves deleted items, adds new items, updates order fields
- Migration scripts: TypeScript (primary), Python, SQL alternatives
Routing Creation (REQUIRED):
- TypeScript Script:
scripts/create_routing_for_order.tsfor automatic routing creation - SQL Script:
scripts/create_routing_for_order.sqlfor manual routing creation - Automatic grouping: CheckItems grouped by post prefix (P3, P4, P5, P6)
- RouteStep generation: Creates steps with sequence, status, assignedCheckItemIds
Key Concepts
CheckItem Structure:
{
"itemSpec": {
"itemId": "P4.801",
"title": "Охлаждающая жидкость: уровень/состояние",
"order": 16,
"block": "Подкапотное пространство",
"priority": "P4",
"fields": [...],
"methodology": "..."
}
}
Available Checklists:
- General Checklist:
TrustOn Bundle v4.9.2.json- standard inspection checklist - Centromash Checklist (current default):
TrustOn Checklist v4.9.2 CM - centromash.v4.9.7.full-from-xlsx.json- Version:
4.0.9.7-final-centromash+full-xlsx - Items: 20 specialized checks
- Focus: XLSX-aligned CM flow for body panels, glass, interior, underhood, underbody, and split suspension checks
- Optimized for: Posts P1, P2, P3
- Version:
- Legacy Centromash Bundles:
TrustOn Checklist v4.9.2 CM - centromash.json,TrustOn Checklist v4.9.2 CM - centromash.v4.9.5.strict.json- Keep only for historical migrations or compatibility checks; do not use as the current default.
Migration Logic:
- Load new bundle (
v4.9.7.full-from-xlsxfor current CM migrations) - Extract itemId → itemSpec mapping
- For each order: iterate CheckItems, update itemSpec where code matches
- Add new items (for example
P4.CM.BODY.PANELS,P6.CM.SUSP.RL,P6.CM.SUSP.RR) if missing - Preserve deleted items (P3.000, P4.700-702, P4.809-810)
- When replacing historical structures, explicitly handle
P6.CM.SUSP.REAR -> P6.CM.SUSP.RL + P6.CM.SUSP.RR - Update
checkItemToPostMapexpectations and routing after the split
Instructions
Step 1: Prepare Bundle
Choose checklist type:
- Centromash: For Centromash diagnostic center orders →
TrustOn Checklist v4.9.2 CM - centromash.v4.9.7.full-from-xlsx.json - General: For standard inspections →
TrustOn Bundle v4.9.2.json
Update script CHECKLIST_PATH (if using TypeScript script):
const CHECKLIST_PATH = path.join(
__dirname,
'../docs/checklist/checklist4/TrustOn Checklist v4.9.2 CM - centromash.v4.9.7.full-from-xlsx.json'
);
Bundle format:
{
"schema": "TrustOn.ChecklistBundle.v2",
"version": "4.0.9.7-final-centromash+full-xlsx",
"items": [
{ "itemId": "P1.010", "title": "...", "order": 1, ... }
],
"optionsRegistries": { ... },
"checkItemToPostMap": { "P4.THK.001": "P4", ... }
}
Step 2: Create Migration Endpoint (NestJS)
Add controller in apps/api/src/inspection/migrate.controller.ts:
Features:
- Load ITEM_SPECS from bundle constant
- Support query params:
orderId,dryRun,confirm - Dry-run mode: returns count of changes without persisting
- Confirm mode: applies migration to all/single orders
- Returns: migration summary (updated count, new items added, etc.)
Step 3: Execute Migration
Option A: TypeScript Script (RECOMMENDED for single orders)
# Migrate single order by orderId:
pnpm tsx scripts/migrate_single_order_checklist.ts <orderId>
# Example (Ford Explorer, Centromash v4.9.7.full-from-xlsx):
pnpm tsx scripts/migrate_single_order_checklist.ts bea653ec-d5d2-4c7f-a3e6-358c68284212
Features:
- Uses Prisma 7 with pg adapter
- Loads checklist from
docs/checklist/checklist4/TrustOn Checklist v4.9.2 CM - centromash.v4.9.7.full-from-xlsx.json - Updates existing CheckItems by matching
codetoitemId - Adds new items not present in order
- Preserves unmatched items with warnings
- Shows detailed migration summary
- Current API default bundle already resolves to
v4.9.7.full-from-xlsxviaapps/api/src/inspection/item-specs.constant.tsandapps/api/src/orders/template-catalog.service.ts
Option B: HTTP Endpoint (for batch migrations)
# Single order test:
curl -X POST http://localhost:3000/migrate/checkitems-v492?orderId=<uuid>
# Dry-run on all orders:
curl -X POST http://localhost:3000/migrate/checkitems-v492?dryRun=true
# Production migration:
curl -X POST http://localhost:3000/migrate/checkitems-v492?confirm=true
Option C: CLI Command
pnpm --filter @truston/api migrate:checkitems-v492 --all --confirm
Option D: Direct SQL
jq -r '.items[] | @json' "$BUNDLE_PATH" | while read SPEC_JSON; do
ITEM_ID=$(echo "$SPEC_JSON" | jq -r '.itemId')
UPDATE "CheckItem" SET "itemSpec" = '$SPEC_JSON' WHERE code = '$ITEM_ID'
done
Step 4: Create Routing for Order
CRITICAL: After migrating CheckItems, you MUST create routing (WorkOrderRouting) for the order to work with the API endpoint /orders/{orderId}/routing.
Option A: TypeScript Script (RECOMMENDED)
# Create routing automatically based on CheckItems:
pnpm tsx scripts/create_routing_for_order.ts <orderId>
# Example:
pnpm tsx scripts/create_routing_for_order.ts bea653ec-d5d2-4c7f-a3e6-358c68284212
What it does:
- Gets all posts from the order's service station
- Groups CheckItems by post prefix (P3, P4, P5, P6, etc.)
- Creates WorkOrderRouting record
- Creates RouteStep records for each post with assigned CheckItems
- Returns routing summary
- For current CM flow, expect rear suspension as two distinct items:
P6.CM.SUSP.RLandP6.CM.SUSP.RR
Option B: SQL Script
# Use pre-generated SQL for specific order:
psql -h <host> -U <user> -d <database> -f scripts/create_routing_for_order.sql
Important Notes:
- RouteStep schema does NOT have
updatedAtfield (Prisma schema only hascreatedAt) - Post assignment is automatic based on CheckItem code prefix
- Special handling:
PH.*items go toP3(Фотозона) - Each RouteStep gets
assignedCheckItemIdsarray
Routing Structure:
WorkOrderRouting
├── orderId (unique)
└── route (RouteStep[])
├── postId
├── sequence (1, 2, 3, 4...)
├── status (pending, in_progress, completed)
└── assignedCheckItemIds (CheckItem.id[])
Step 5: Verify Results
Check CheckItems migration:
SELECT
COUNT(*) as total_updated,
COUNT(DISTINCT "order"::text) as unique_orders
FROM "CheckItem"
WHERE "itemSpec"->>'order' IS NOT NULL;
-- Check specific post (e.g., P4)
SELECT code, "itemSpec"->>'order' as "order", "itemSpec"->>'title' as title
FROM "CheckItem"
WHERE code LIKE 'P4.%'
GROUP BY code, "order"
ORDER BY ("itemSpec"->>'order')::int;
Check routing creation:
-- Verify routing exists
SELECT * FROM "WorkOrderRouting" WHERE "orderId" = '<orderId>';
-- Check route steps
SELECT
wr.id as routing_id,
rs."postId",
p.code as post_code,
p.name as post_name,
rs.sequence,
rs.status,
array_length(rs."assignedCheckItemIds", 1) as check_items_count
FROM "WorkOrderRouting" wr
JOIN "RouteStep" rs ON rs."workOrderRoutingId" = wr.id
JOIN "Post" p ON p.id = rs."postId"
WHERE wr."orderId" = '<orderId>'
ORDER BY rs.sequence;
Test API endpoint:
# Should return 200 with routing data (not 404):
curl https://api.thetasystem.com/orders/<orderId>/routing
Migration Workflow
1. TypeSpec contracts updated
↓
2. pnpm gen (generates new bundle)
↓
3. Create migration endpoint/script
↓
4. Test on single order (dryRun or single orderId)
↓
5. Verify order field updates, especially any split mappings such as `P6.CM.SUSP.REAR -> P6.CM.SUSP.RL/RR`
↓
6. Create routing for order (CRITICAL STEP)
↓
7. Test API endpoint GET /orders/{orderId}/routing
↓
8. Execute on all orders (confirm=true)
↓
9. Verify counts match expectations
↓
10. Commit migration script to separate branch
Data Preservation Rules
- Deleted items: Keep as-is (P3.000, P4.700-702, P4.809-810)
- New items: Add with full spec if missing
- Updated items: Replace entire itemSpec (order + metadata)
- Unmatched items: Log warnings, preserve unchanged
- Split items: When a historical item is replaced by multiple current items, preserve old records unless the migration explicitly deprecates them, and create the new split records with full specs.
Files to Create
# CheckItem Migration
scripts/migrate_single_order_checklist.ts # TypeScript migration script (PRIMARY)
apps/api/src/inspection/migrate.controller.ts # HTTP endpoint (batch migrations)
apps/api/src/inspection/migrate-checkitems.command.ts # CLI command
scripts/migrate_checkitem_v{VERSION}.py # Python alternative
scripts/migrate-checkitems.sql # Direct SQL
# Routing Creation (REQUIRED after migration)
scripts/create_routing_for_order.ts # TypeScript routing script (PRIMARY)
scripts/create_routing_for_order.sql # SQL routing script
TypeScript Migration Script Template:
- Import
dotenv/configto load DATABASE_URL - Use
PrismaPgadapter withPool(Prisma 7 requirement) - Read checklist bundle JSON from
docs/checklist/checklist4/ - Build itemId → itemSpec mapping
- Update existing CheckItems by code
- Create new CheckItems with required fields (title, claimTemplate, required)
- Close pool connection after migration
TypeScript Routing Script Template:
- Import
dotenv/configto load DATABASE_URL - Use
PrismaPgadapter withPool(Prisma 7 requirement) - Get order and service station posts
- Group CheckItems by post prefix (P3, P4, P5, P6)
- Create WorkOrderRouting record
- Create RouteStep records (WITHOUT updatedAt field)
- Each RouteStep includes: postId, sequence, status, assignedCheckItemIds
- Close pool connection after creation
Testing Checklist
CheckItem Migration:
- [ ] Dry-run returns correct count of changes
- [ ] Order field updates for key items (P4.801, P6.010, etc.)
- [ ] New items added to all orders
- [ ]
P6.CM.SUSP.REARreplacement logic createsP6.CM.SUSP.RLandP6.CM.SUSP.RRwhere required - [ ] Deleted items preserved
- [ ] Post order sequence maintained (1-25 for P4)
- [ ] Run on single order first
- [ ] Verify on 2-3 random orders before batch
- [ ] Check database row counts match
Routing Creation:
- [ ] WorkOrderRouting record created for order
- [ ] RouteStep records created for all relevant posts
- [ ] CheckItems correctly grouped by post prefix
- [ ] Sequence numbers are sequential (1, 2, 3, 4...)
- [ ] assignedCheckItemIds arrays populated
- [ ] All RouteStep statuses set to 'pending'
- [ ] API endpoint
/orders/{orderId}/routingreturns 200 (not 404) - [ ] No
updatedAtfield errors in RouteStep creation
Common Issues
Issue: PrismaClient initialization error (Prisma 7) Solution:
import 'dotenv/config';
import { PrismaPg } from '@prisma/adapter-pg';
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
Issue: Missing required field title when creating CheckItem
Solution: Include all required fields in create:
await prisma.checkItem.create({
data: {
orderId,
code: item.itemId,
title: item.title,
claimTemplate: `Claim for ${item.itemId}`,
required: item.required,
itemSpec: item as any,
},
});
Issue: Order field not updating Solution: Ensure itemSpec is loaded as JSON object, not string
Issue: Unmatched items in logs Solution: Check itemId format matches between bundle and database
Issue: 404 Not Found on /orders/{orderId}/routing endpoint
Solution: Routing not created for order. Run routing creation script:
pnpm tsx scripts/create_routing_for_order.ts <orderId>
Issue: RouteStep creation fails with "updatedAt does not exist"
Solution: RouteStep table does NOT have updatedAt field. Remove it from INSERT:
// ❌ Wrong (has updatedAt)
await prisma.routeStep.create({
data: { ...fields, createdAt: new Date(), updatedAt: new Date() }
});
// ✅ Correct (only createdAt)
await prisma.routeStep.create({
data: { ...fields, createdAt: new Date() }
});
Example Results
Example 1: Single Order (Ford Explorer, Centromash v4.9.7.full-from-xlsx)
Order ID: bea653ec-d5d2-4c7f-a3e6-358c68284212
VIN: 1FM5K8HC0LGA87502
Status: in_progress
Checklist version: 4.0.9.7-final-centromash+full-xlsx
Updated items: 0 (order had no existing items)
New items added: 20
- ✓ P1.CM.RECEPTION: Приемка на станции
- ✓ P1.CM.WASH: Мойка
- ✓ PH.PHOTO.STANDARD: Фотофиксация (стандартный набор)
- ✓ P4.THK.002: Проверка ультрафиолетовым сканером
- ✓ P4.THK.001: Проверка толщиномером
- ✓ P4.GLASS.INSPECT: Осмотр остекления
- ✓ P4.LIGHT.INSPECT: Осмотр световых приборов
- ✓ P4.MISC.BOOT: Багажное отделение
- ✓ P4.INT.INSPECT: Осмотр салона
- ✓ P4.600: OBD скан всех блоков
- ✓ P4.CM.BODY.PANELS: Осмотр кузовных панелей (Centromash)
- ✓ P4.CM.UNDERHOOD: Подкапотное пространство
- ✓ P5.CM.BRAKE_STAND: Тормозной стенд (Centromash)
- ✓ P6.CM.UNDERBODY: Подъемник: защиты и днище
- ✓ P6.CM.LIFT: Подъемник (Centromash)
- ✓ P6.CM.TESTDRIVE: Тест-драйв
- ✓ P6.CM.SUSP.FL: Подвеска переднего левого колеса
- ✓ P6.CM.SUSP.FR: Подвеска переднего правого колеса
- ✓ P6.CM.SUSP.RL: Подвеска заднего левого колеса
- ✓ P6.CM.SUSP.RR: Подвеска заднего правого колеса
Total items after migration: 20
Routing creation:
Routing ID: 41c3983c-b04b-463b-9066-bcf556a1ed2a
Order ID: bea653ec-d5d2-4c7f-a3e6-358c68284212
Route steps:
1. P1 - Приемка / мойка
Status: pending
Items: 2 (P1.CM.RECEPTION, P1.CM.WASH)
2. P2 - Кузовной осмотр
Status: pending
Items: 10 (PH.PHOTO.STANDARD, P4.THK.001, P4.THK.002, P4.CM.BODY.PANELS, etc.)
3. P3 - Подъемник / тормозной стенд
Status: pending
Items: 8 (P5.CM.BRAKE_STAND, P6.CM.LIFT, P6.CM.UNDERBODY, P6.CM.SUSP.FL, P6.CM.SUSP.FR, P6.CM.SUSP.RL, P6.CM.SUSP.RR, P6.CM.TESTDRIVE)
API endpoint test:
curl https://api.thetasystem.com/orders/bea653ec-d5d2-4c7f-a3e6-358c68284212/routing
# Returns 200 OK with routing data ✅
Example 2: Batch Migration (26 orders, general checklist)
- 2763 CheckItems updated
- 52 new items added (P4.MISC.BOOT, P4.MISC.HOOD)
- 52 deleted items preserved
- Order range: 1-206
- Post 4 sequence: 25 items, orders 1-25
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.