1 #!/bin/bash
2 # Copy backend files from backup to workspace and fix known import patterns.
3 # Usage: bash fullstack_copy_backend.sh [--schema-path <path>] [--route-layout single|directory]
4 #
5 # If flags are omitted, the script auto-discovers from .migration-backup/.
6 # Prints a summary of what was copied and what needs agent attention.
7
8 set -euo pipefail
9
10 BACKUP=".migration-backup"
11 SCHEMA_PATH=""
12 ROUTE_LAYOUT=""
13
14 while [[ $# -gt 0 ]]; do
15 case "$1" in
16 --schema-path) SCHEMA_PATH="$2"; shift 2 ;;
17 --route-layout) ROUTE_LAYOUT="$2"; shift 2 ;;
18 *) echo "Unknown arg: $1"; exit 1 ;;
19 esac
20 done
21
22 echo "==== BACKEND COPY ===="
23
24 # --- Auto-discover if not specified ---
25 if [ -z "$SCHEMA_PATH" ]; then
26 for candidate in \
27 "$BACKUP/shared/schema.ts" \
28 "$BACKUP/shared/schema/index.ts" \
29 "$BACKUP/db/schema.ts" \
30 "$BACKUP/server/db/schema.ts" \
31 "$BACKUP/src/shared/schema.ts"; do
32 if [ -f "$candidate" ]; then
33 SCHEMA_PATH="${candidate#"$BACKUP/"}"
34 break
35 fi
36 done
37 # Fallback: broader search (matches fullstack_detect.sh behavior)
38 if [ -z "$SCHEMA_PATH" ]; then
39 FOUND=$(find "$BACKUP" -name "schema.ts" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -1)
40 if [ -n "$FOUND" ]; then
41 SCHEMA_PATH="${FOUND#"$BACKUP/"}"
42 fi
43 fi
44 fi
45
46 if [ -z "$ROUTE_LAYOUT" ]; then
47 if [ -d "$BACKUP/server/routes" ]; then
48 ROUTE_LAYOUT="directory"
49 elif [ -f "$BACKUP/server/routes.ts" ]; then
50 ROUTE_LAYOUT="single"
51 else
52 ROUTE_LAYOUT="none"
53 fi
54 fi
55
56 # --- Copy schema ---
57 if [ -n "$SCHEMA_PATH" ] && [ -f "$BACKUP/$SCHEMA_PATH" ]; then
58 # Handle both single file and directory schemas
59 SCHEMA_DIR=$(dirname "$BACKUP/$SCHEMA_PATH")
60 SCHEMA_BASENAME=$(basename "$SCHEMA_PATH")
61
62 if [ "$SCHEMA_BASENAME" = "index.ts" ]; then
63 # Directory-style schema — copy entire directory
64 cp -r "$SCHEMA_DIR"/* lib/db/src/schema/
65 echo "COPIED: $SCHEMA_PATH (directory) → lib/db/src/schema/"
66 else
67 cp "$BACKUP/$SCHEMA_PATH" lib/db/src/schema/
68 echo "COPIED: $SCHEMA_PATH → lib/db/src/schema/"
69
70 # Update the barrel export so @workspace/db re-exports the schema
71 SCHEMA_MODULE=$(basename "$SCHEMA_PATH" .ts)
72 if [ -f lib/db/src/schema/index.ts ]; then
73 # Replace the empty `export {}` with an actual export
74 if grep -q 'export {}' lib/db/src/schema/index.ts; then
75 sed -i "s|export {}|export * from \"./$SCHEMA_MODULE\";|" lib/db/src/schema/index.ts
76 elif ! grep -q "from \"./$SCHEMA_MODULE\"" lib/db/src/schema/index.ts; then
77 echo "export * from \"./$SCHEMA_MODULE\";" >> lib/db/src/schema/index.ts
78 fi
79 echo "UPDATED: lib/db/src/schema/index.ts → exports $SCHEMA_MODULE"
80 fi
81 fi
82
83 # Fix zod imports in all copied schema files
84 find lib/db/src/schema/ -name "*.ts" -exec sed -i 's/from "zod"/from "zod\/v4"/g' {} + 2>/dev/null || true
85 find lib/db/src/schema/ -name "*.ts" -exec sed -i "s/from 'zod'/from 'zod\/v4'/g" {} + 2>/dev/null || true
86 # Fix zod v4 API changes
87 find lib/db/src/schema/ -name "*.ts" -exec sed -i 's/z\.record(z\.any())/z.record(z.string(), z.any())/g' {} + 2>/dev/null || true
88 find lib/db/src/schema/ -name "*.ts" -exec sed -i 's/\.errors/\.issues/g' {} + 2>/dev/null || true
89 echo "FIXED: zod → zod/v4 imports + API compat in schema files"
90 else
91 echo "WARNING: No schema file found — agent must locate and copy manually"
92 fi
93
94 # --- Copy routes ---
95 COPIED_ROUTES=0
96 case "$ROUTE_LAYOUT" in
97 single)
98 cp "$BACKUP/server/routes.ts" artifacts/api-server/src/routes/routes.ts
99 echo "COPIED: server/routes.ts → artifacts/api-server/src/routes/routes.ts"
100 # Fix relative imports — routes.ts moved from server/ to server/routes/,
101 # so sibling imports like ./storage need to become ../storage
102 sed -i 's|from "\./|from "../|g' artifacts/api-server/src/routes/routes.ts 2>/dev/null || true
103 sed -i "s|from '\./|from '../|g" artifacts/api-server/src/routes/routes.ts 2>/dev/null || true
104 echo "FIXED: relative imports in routes.ts (adjusted for routes/ subdirectory)"
105 COPIED_ROUTES=1
106 ;;
107 directory)
108 cp -r "$BACKUP/server/routes/"* artifacts/api-server/src/routes/
109 echo "COPIED: server/routes/* → artifacts/api-server/src/routes/"
110 COPIED_ROUTES=1
111 ;;
112 none)
113 echo "WARNING: No routes found — agent must locate and copy manually"
114 ;;
115 esac
116
117 # --- Copy storage ---
118 if [ -f "$BACKUP/server/storage.ts" ]; then
119 cp "$BACKUP/server/storage.ts" artifacts/api-server/src/storage.ts
120 echo "COPIED: server/storage.ts → artifacts/api-server/src/storage.ts"
121 fi
122
123 # --- Copy remaining server files and directories ---
124 if [ -d "$BACKUP/server" ]; then
125 # Copy top-level .ts files (skip already-copied and infrastructure)
126 for f in "$BACKUP/server/"*.ts; do
127 [ -f "$f" ] || continue
128 basename=$(basename "$f")
129 case "$basename" in
130 routes.ts|storage.ts|index.ts|main.ts|vite.ts) continue ;;
131 esac
132 cp "$f" artifacts/api-server/src/
133 echo "COPIED: server/$basename → artifacts/api-server/src/$basename"
134 done
135 # Copy nested directories (middleware, lib, utils, integrations, etc.)
136 # Skip routes/ (already copied), node_modules, and dist/build output
137 for dir in "$BACKUP/server"/*/; do
138 [ ! -d "$dir" ] && continue
139 dirname=$(basename "$dir")
140 case "$dirname" in
141 routes|node_modules|dist|build|__tests__|__mocks__) continue ;;
142 esac
143 cp -r "$dir" "artifacts/api-server/src/$dirname"
144 echo "COPIED: server/$dirname/ → artifacts/api-server/src/$dirname/"
145 done
146 fi
147
148 # --- Fix import patterns in all copied server files (recursive) ---
149 # Only rewrite schema imports to @workspace/db. Leave other @shared/ imports
150 # (auth, models, utils) for the agent — they need to go to different packages.
151 find artifacts/api-server/src/ -name "*.ts" -exec sed -i 's|from "../../shared/schema"|from "@workspace/db"|g' {} + 2>/dev/null || true
152 find artifacts/api-server/src/ -name "*.ts" -exec sed -i "s|from '../../shared/schema'|from '@workspace/db'|g" {} + 2>/dev/null || true
153 find artifacts/api-server/src/ -name "*.ts" -exec sed -i 's|from "@shared/schema"|from "@workspace/db"|g' {} + 2>/dev/null || true
154 find artifacts/api-server/src/ -name "*.ts" -exec sed -i "s|from '@shared/schema'|from '@workspace/db'|g" {} + 2>/dev/null || true
155 # Flag any remaining @shared/ or ../../shared/ imports the agent needs to fix
156 REMAINING_SHARED=$(find artifacts/api-server/src/ -name "*.ts" -exec grep -l "@shared/\|../../shared/" {} + 2>/dev/null || true)
157 if [ -n "$REMAINING_SHARED" ]; then
158 echo "WARNING: non-schema @shared/ imports found — agent must relocate these manually:"
159 echo "$REMAINING_SHARED" | while read -r f; do echo " $f"; done
160 fi
161 # Fix zod v4 in server files too (routes may use zod for validation)
162 find artifacts/api-server/src/ -name "*.ts" -exec sed -i 's/from "zod"/from "zod\/v4"/g' {} + 2>/dev/null || true
163 find artifacts/api-server/src/ -name "*.ts" -exec sed -i "s/from 'zod'/from 'zod\/v4'/g" {} + 2>/dev/null || true
164 find artifacts/api-server/src/ -name "*.ts" -exec sed -i 's/z\.record(z\.any())/z.record(z.string(), z.any())/g' {} + 2>/dev/null || true
165 echo "FIXED: schema imports → @workspace/db + zod v4 compat in server files"
166
167 # --- Copy attached assets ---
168 if [ -d "$BACKUP/attached_assets" ]; then
169 cp -r "$BACKUP/attached_assets" .
170 echo "COPIED: attached_assets/"
171 fi
172
173 echo ""
174 echo "==== BACKEND COPY COMPLETE ===="
175 echo ""
176 echo "AGENT TODO:"
177 echo " 1. Convert route signature (registerRoutes → Express router)"
178 echo " 2. Write OpenAPI spec based on routes"
179 echo " 3. Add @workspace/api-zod imports where needed"
180 if [ $COPIED_ROUTES -eq 0 ]; then
181 echo " 4. Locate and copy route files manually"
182 fi