|
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 |