Răsfoiți Sursa

patch: update setup file in order to match migrations update

Fernando 3 săptămâni în urmă
părinte
comite
5c5203ad6e
1 a modificat fișierele cu 175 adăugiri și 67 ștergeri
  1. 175 67
      bin/setup

+ 175 - 67
bin/setup

@@ -1,87 +1,199 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
-set -euo pipefail
+set -Eeuo pipefail
 
-# Caminhos
 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
-MIGRATIONS_FILE="${ROOT_DIR}/migrations/migrations_v1.sql"
+MIGRATIONS_DIR="${ROOT_DIR}/migrations"
+
+require_cmd() {
+  if ! command -v "$1" >/dev/null 2>&1; then
+    echo "[setup] ERRO: comando '$1' não encontrado. Instale-o e tente novamente." >&2
+    exit 1
+  fi
+}
+
+require_cmd psql
+require_cmd php
 
-# Carrega variáveis do .env se existir
 if [[ -f "${ROOT_DIR}/.env" ]]; then
   set -a
   # shellcheck disable=SC1090
-  source "${ROOT_DIR}/.env"
+  source <(sed $'s/\r$//' "${ROOT_DIR}/.env")
   set +a
 fi
 
-# Configurações de conexão (PostgreSQL)
-DB_HOST=${DB_HOST}
-DB_PORT=${DB_PORT}
-DB_NAME=${DB_NAME}
-DB_USER=${DB_USER}
-DB_PASSWORD=${DB_PASSWORD}
+for var in DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD; do
+  if [[ -z "${!var:-}" ]]; then
+    echo "[setup] ERRO: variável ${var} não definida (.env)." >&2
+    exit 1
+  fi
+done
 
-echo "[setup] Host=${DB_HOST} Port=${DB_PORT} DB=${DB_NAME} User=${DB_USER}"
+DB_SUPERUSER="${DB_SUPERUSER:-${DB_USER}}"
+DB_SUPERUSER_PASSWORD="${DB_SUPERUSER_PASSWORD:-${DB_PASSWORD}}"
+DB_SUPERUSER_DB="${DB_SUPERUSER_DB:-postgres}"
+
+run_psql() {
+  local db="$1"
+  shift
+  PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${db}" "$@"
+}
+
+run_psql_super() {
+  local db="${1:-${DB_SUPERUSER_DB}}"
+  shift
+  PGPASSWORD="${DB_SUPERUSER_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_SUPERUSER}" -d "${db}" "$@"
+}
+
+database_exists() {
+  local exists
+  exists="$(run_psql_super "${DB_SUPERUSER_DB}" -tAc "SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'" | tr -d '[:space:]')"
+  [[ "${exists}" == "1" ]]
+}
+
+ensure_migrations_table() {
+  run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<'SQL'
+CREATE TABLE IF NOT EXISTS migrations_run (
+  filename TEXT PRIMARY KEY,
+  applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+SQL
+}
 
-if [[ ! -f "${MIGRATIONS_FILE}" ]]; then
-  echo "[setup] ERRO: Arquivo de migração não encontrado: ${MIGRATIONS_FILE}" >&2
+migration_already_applied() {
+  local name="$1"
+  local result
+  result="$(run_psql "${DB_NAME}" -tAc "SELECT 1 FROM migrations_run WHERE filename='${name//\'/''}'" | tr -d '[:space:]')"
+  [[ "${result}" == "1" ]]
+}
+
+record_migration_applied() {
+  local name="$1"
+  run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 -c "INSERT INTO migrations_run (filename) VALUES ('${name//\'/''}') ON CONFLICT (filename) DO NOTHING;"
+}
+
+bootstrap_migrations_state() {
+  local count
+  count="$(run_psql "${DB_NAME}" -tAc "SELECT COUNT(*) FROM migrations_run" | tr -d '[:space:]')"
+  if [[ "${count}" -gt 0 ]]; then
+    return
+  fi
+
+  local chain_reg
+  chain_reg="$(run_psql "${DB_NAME}" -tAc "SELECT to_regclass('public.chain')" | tr -d '[:space:]')"
+  if [[ -n "${chain_reg}" ]]; then
+    record_migration_applied "migrations_v1.sql"
+  fi
+
+  local cpr_col
+  cpr_col="$(run_psql "${DB_NAME}" -tAc "SELECT 1 FROM information_schema.columns WHERE table_name='cpr' AND column_name='user_id'" | tr -d '[:space:]')"
+  if [[ "${cpr_col}" == "1" ]]; then
+    record_migration_applied "migration_user_id.sql"
+  fi
+}
+
+if [[ ! -d "${MIGRATIONS_DIR}" ]]; then
+  echo "[setup] ERRO: diretório de migrações inexistente (${MIGRATIONS_DIR})." >&2
   exit 1
 fi
 
-echo "[setup] Resetando banco '${DB_NAME}' (DROP/CREATE)..."
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d postgres -v ON_ERROR_STOP=1 -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='${DB_NAME}' AND pid <> pg_backend_pid();"
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d postgres -v ON_ERROR_STOP=1 -c "DROP DATABASE IF EXISTS \"${DB_NAME}\";"
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE \"${DB_NAME}\";"
+collect_migrations() {
+  local -a ordered=()
+  local primary="${MIGRATIONS_DIR}/migrations_v1.sql"
+  if [[ -f "${primary}" ]]; then
+    ordered+=("${primary}")
+  fi
+
+  local -a extras=()
+  local file
+  shopt -s nullglob
+  for file in "${MIGRATIONS_DIR}"/*.sql; do
+    [[ "${file}" == "${primary}" ]] && continue
+    extras+=("${file}")
+  done
+  shopt -u nullglob
 
-# 2) Executa migração (schema) somente se ainda não existir
-echo "[setup] Verificando schema..."
-if [[ -z "$(PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -tAc "SELECT to_regclass('public.company')")" ]]; then
-  echo "[setup] Aplicando migrações do arquivo: ${MIGRATIONS_FILE}"
-  PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -f "${MIGRATIONS_FILE}"
+  if (( ${#extras[@]} )); then
+    # shellcheck disable=SC2207
+    extras=($(printf '%s\n' "${extras[@]}" | sort))
+    ordered+=("${extras[@]}")
+  fi
+
+  if (( ${#ordered[@]} == 0 )); then
+    echo "[setup] ERRO: nenhum arquivo .sql encontrado em ${MIGRATIONS_DIR}." >&2
+    exit 1
+  fi
+
+  MIGRATION_FILES=("${ordered[@]}")
+}
+
+collect_migrations
+
+echo "[setup] Host=${DB_HOST} Port=${DB_PORT} DB=${DB_NAME} User=${DB_USER}"
+
+echo "[setup] Verificando existência do banco '${DB_NAME}'..."
+if database_exists; then
+  echo "[setup] Banco já existe. Pulando recriação."
 else
-  echo "[setup] Schema já existente. Pulando migrações."
+  echo "[setup] Banco não encontrado. Criando..."
+  run_psql_super "${DB_SUPERUSER_DB}" -v ON_ERROR_STOP=1 -c "CREATE DATABASE \"${DB_NAME}\";"
 fi
 
-# 3) Seed inicial (idempotente)
-echo "[setup] Inserindo dados iniciais (seed)..."
+ensure_migrations_table
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"company\" (company_name, company_flag, company_cnpj)
+bootstrap_migrations_state
+
+echo "[setup] Aplicando migrações..."
+for migration in "${MIGRATION_FILES[@]}"; do
+  name="$(basename "${migration}")"
+  if migration_already_applied "${name}"; then
+    echo "  -> ${name} (já aplicada, pulando)"
+    continue
+  fi
+
+  echo "  -> ${name}"
+  run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 -f "${migration}"
+  record_migration_applied "${name}"
+done
+
+echo "[setup] Inserindo dados iniciais (seed)..."
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "company" (company_name, company_flag, company_cnpj)
 SELECT 'LumyonTech', 'a', '${COMPANY_CNPJ:-00000000000000}'
-WHERE NOT EXISTS (SELECT 1 FROM \"company\" WHERE company_name = 'LumyonTech');
-"
+WHERE NOT EXISTS (SELECT 1 FROM "company" WHERE company_name = 'LumyonTech');
+SQL
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"role\" (company_id, role_name, role_permission, role_flag)
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "role" (company_id, role_name, role_permission, role_flag)
 SELECT c.company_id, 'Admin', '{}'::jsonb, 'a'
-FROM \"company\" c
+FROM "company" c
 WHERE c.company_name = 'LumyonTech'
   AND NOT EXISTS (
-    SELECT 1 FROM \"role\" r WHERE r.role_name = 'Admin' AND r.company_id = c.company_id
+    SELECT 1 FROM "role" r WHERE r.role_name = 'Admin' AND r.company_id = c.company_id
   );
-"
+SQL
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"status\" (status_status)
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "status" (status_status)
 SELECT 'PENDING'
-WHERE NOT EXISTS (SELECT 1 FROM \"status\" WHERE status_status = 'PENDING');
-"
+WHERE NOT EXISTS (SELECT 1 FROM "status" WHERE status_status = 'PENDING');
+SQL
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"chain\" (chain_name)
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "chain" (chain_name)
 SELECT 'polygon'
-WHERE NOT EXISTS (SELECT 1 FROM \"chain\" WHERE chain_name = 'polygon');
-"
+WHERE NOT EXISTS (SELECT 1 FROM "chain" WHERE chain_name = 'polygon');
+SQL
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"commodities\" (commodities_name, commodities_flag)
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "commodities" (commodities_name, commodities_flag)
 SELECT 'soja', 'a'
-WHERE NOT EXISTS (SELECT 1 FROM \"commodities\" WHERE commodities_name = 'soja');
-"
+WHERE NOT EXISTS (SELECT 1 FROM "commodities" WHERE commodities_name = 'soja');
+SQL
 
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"wallet\" (
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "wallet" (
   company_id,
   wallet_public_key,
   wallet_address,
@@ -102,7 +214,7 @@ WHERE c.company_name = 'LumyonTech'
     SELECT 1 FROM "wallet" w
     WHERE w.wallet_address = '0x0166117cE1C182D0Cf5cf605A2C07BB87C278F85'
   );
-"
+SQL
 
 DEFAULT_USER_NAME="${DEFAULT_USER_NAME:-Admin}"
 DEFAULT_USER_EMAIL="${DEFAULT_USER_EMAIL:-admin@lumyon.tech}"
@@ -116,12 +228,13 @@ DEFAULT_USER_COUNTRY="${DEFAULT_USER_COUNTRY:-BR}"
 DEFAULT_USER_KYC="${DEFAULT_USER_KYC:-0}"
 DEFAULT_USER_BIRTHDATE="${DEFAULT_USER_BIRTHDATE:-0}"
 DEFAULT_USER_CPF="${DEFAULT_USER_CPF:-00000000000}"
+DEFAULT_USER_KYC_EXTERNAL_ID="${DEFAULT_USER_KYC_EXTERNAL_ID:-default-kyc-id}"
 
 echo "[setup] Inserindo usuário padrão (${DEFAULT_USER_EMAIL})..."
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -v ON_ERROR_STOP=1 -c "
-INSERT INTO \"user\" (
+run_psql "${DB_NAME}" -v ON_ERROR_STOP=1 <<SQL
+INSERT INTO "user" (
   user_name, user_email, user_password, user_phone, user_address, user_city, user_state, user_zip, user_country,
-  user_kyc, user_birthdate, user_cpf, company_id, role_id, user_flag
+  user_kyc, kyc_external_id, user_birthdate, user_cpf, company_id, role_id, user_flag
 )
 SELECT
   '${DEFAULT_USER_NAME}',
@@ -134,24 +247,19 @@ SELECT
   '${DEFAULT_USER_ZIP}',
   '${DEFAULT_USER_COUNTRY}',
   ${DEFAULT_USER_KYC}::int,
+  '${DEFAULT_USER_KYC_EXTERNAL_ID}',
   ${DEFAULT_USER_BIRTHDATE}::int,
   '${DEFAULT_USER_CPF}',
   c.company_id,
   r.role_id,
   'a'
-FROM \"company\" c
-JOIN \"role\" r ON r.company_id = c.company_id AND r.role_name = 'Admin'
+FROM "company" c
+JOIN "role" r ON r.company_id = c.company_id AND r.role_name = 'Admin'
 WHERE c.company_name = 'LumyonTech'
-  AND NOT EXISTS (SELECT 1 FROM \"user\" u WHERE u.user_email = '${DEFAULT_USER_EMAIL}');
-"
+  AND NOT EXISTS (SELECT 1 FROM "user" u WHERE u.user_email = '${DEFAULT_USER_EMAIL}');
+SQL
 
-# 4) Resumo
 echo "[setup] Finalizado com sucesso!"
-echo "[setup] Tabelas seed (amostra):"
-PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -c "
-TABLE \"company\";
-TABLE \"role\";
-TABLE \"status\";
-TABLE \"chain\";
-TABLE \"user\";
-" | sed 's/\x1b\[[0-9;]*m//g'
+run_psql "${DB_NAME}" <<'SQL'
+\dt+ public.*
+SQL