fix(number-fields): избегаем потери точности длинных чисел
- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
This commit is contained in:
75
scripts/dev/sync-from-prod-deps.sh
Executable file
75
scripts/dev/sync-from-prod-deps.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Sync production database into the local development database.
|
||||
# Use this when running the app natively with `npm run dev` and Docker deps only.
|
||||
# Usage: scripts/dev/sync-from-prod-deps.sh
|
||||
#
|
||||
# Requires:
|
||||
# - SSH access to production server via id_ed25519_crm
|
||||
# - Dependencies are running (scripts/dev/start-deps.sh)
|
||||
# - .env.local exists with DATABASE_URL pointing to localhost:5432
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
||||
PROJECT_NAME="crm-local"
|
||||
COMPOSE_FILE="${PROJECT_ROOT}/docker-compose.deps.yml"
|
||||
SSH_HOST="root@82.202.130.22"
|
||||
DUMP_FILE="${PROJECT_ROOT}/tmp/crm-prod-sync.dump.gz"
|
||||
|
||||
# Resolve SSH key
|
||||
if [[ -n "${CRM_SSH_KEY:-}" && -f "${CRM_SSH_KEY}" ]]; then
|
||||
SSH_KEY="${CRM_SSH_KEY}"
|
||||
elif [[ -f "${HOME}/.ssh/id_ed25519_crm" ]]; then
|
||||
SSH_KEY="${HOME}/.ssh/id_ed25519_crm"
|
||||
elif [[ -f "${PROJECT_ROOT}/../.ssh_id_ed25519_crm" ]]; then
|
||||
SSH_KEY="${PROJECT_ROOT}/../.ssh_id_ed25519_crm"
|
||||
else
|
||||
echo "ERROR: SSH key not found."
|
||||
echo "Set CRM_SSH_KEY or place id_ed25519_crm in ~/.ssh/ or project parent folder."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
if [[ ! -f .env.local ]]; then
|
||||
echo "ERROR: .env.local not found. Copy .env.local.example to .env.local and fill secrets."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p tmp
|
||||
|
||||
echo "=== 1. Testing SSH connection ==="
|
||||
ssh -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout=10 -i "${SSH_KEY}" "${SSH_HOST}" 'echo SSH_OK' || {
|
||||
echo "ERROR: Cannot connect to production server."
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "=== 2. Dumping production database ==="
|
||||
ssh -o IdentitiesOnly=yes -i "${SSH_KEY}" "${SSH_HOST}" \
|
||||
'docker exec -i crm-db-1 pg_dump -U appuser -d appdb -Fc' | gzip > "${DUMP_FILE}"
|
||||
echo "Dump saved to: ${DUMP_FILE}"
|
||||
|
||||
echo "=== 3. Stopping and recreating local database ==="
|
||||
docker compose -f "${COMPOSE_FILE}" -p "${PROJECT_NAME}" stop db
|
||||
docker compose -f "${COMPOSE_FILE}" -p "${PROJECT_NAME}" rm -f db
|
||||
docker volume rm "${PROJECT_NAME}_postgres_data" >/dev/null 2>&1 || true
|
||||
docker compose -f "${COMPOSE_FILE}" -p "${PROJECT_NAME}" up -d db
|
||||
|
||||
echo "=== 4. Waiting for local database ==="
|
||||
for i in {1..30}; do
|
||||
if docker exec "${PROJECT_NAME}-db-1" pg_isready -U appuser -d appdb >/dev/null 2>&1; then
|
||||
echo "Database is ready"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "=== 5. Restoring dump to local database ==="
|
||||
zcat "${DUMP_FILE}" | docker exec -i "${PROJECT_NAME}-db-1" pg_restore -U appuser -d appdb --clean --if-exists
|
||||
|
||||
echo ""
|
||||
echo "=== Sync complete ==="
|
||||
echo "Start the app with: npm run dev"
|
||||
echo "Dump file kept at: ${DUMP_FILE}"
|
||||
echo "You can delete it manually when no longer needed."
|
||||
Reference in New Issue
Block a user