fix: clean stale deployments before monolith start

This commit is contained in:
Deploy
2026-08-25 21:59:29 +02:00
parent 9ae5f8e0de
commit 66a08b61d2
4 changed files with 89 additions and 22 deletions

View File

@@ -890,6 +890,7 @@ function Field({
required = false, required = false,
min, min,
max, max,
placeholder,
}: { }: {
label: string; label: string;
value: string; value: string;
@@ -898,6 +899,7 @@ function Field({
required?: boolean; required?: boolean;
min?: number; min?: number;
max?: number; max?: number;
placeholder?: string;
}) { }) {
return ( return (
<label className="text-sm font-medium text-gray-700"> <label className="text-sm font-medium text-gray-700">
@@ -909,6 +911,7 @@ function Field({
required={required} required={required}
min={min} min={min}
max={max} max={max}
placeholder={placeholder}
className="mt-1 w-full rounded-xl border border-gray-300 px-3 py-2.5" className="mt-1 w-full rounded-xl border border-gray-300 px-3 py-2.5"
/> />
</label> </label>

View File

@@ -0,0 +1,17 @@
/**
* Compatibility marker for the historical payment partial-refund migration.
*
* Some long-lived local databases have this migration recorded in pgmigrations,
* but the repository no longer carried the file. node-pg-migrate rejects later
* migrations when an already-run migration is missing from disk, so keep this
* no-op marker to preserve ordering between 060 and 062.
*
* Current partial-refund schema support is already covered by previous
* reporting/POS migrations (notably 053 and 056).
*/
/** @param {import('pg-migrate').MigrationBuilder} _pgm */
export const up = (_pgm) => {};
/** @param {import('pg-migrate').MigrationBuilder} _pgm */
export const down = (_pgm) => {};

View File

@@ -10,7 +10,9 @@ exports.up = (pgm) => {
default: null, default: null,
}, },
}); });
pgm.addCommentOnColumn('pos_stores', 'logo_url', 'URL del logo custom para tickets TPV. Si es null, se usa el logo default /images/logo-main.png'); pgm.sql(
"COMMENT ON COLUMN pos_stores.logo_url IS 'URL del logo custom para tickets TPV. Si es null, se usa el logo default /images/logo-main.png'",
);
}; };
exports.down = (pgm) => { exports.down = (pgm) => {

View File

@@ -130,6 +130,69 @@ port_pid() {
fi fi
} }
port_pids() {
local port="$1"
if command -v lsof >/dev/null 2>&1; then
lsof -nP -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null | sort -u || true
fi
}
stop_pid() {
local pid="$1" label="$2" deadline
[[ -n "$pid" ]] || return 0
if ! kill -0 "$pid" 2>/dev/null; then
return 0
fi
echo "[INFO] Stopping $label (PID $pid)..."
kill -TERM "$pid" 2>/dev/null || true
deadline=$((SECONDS + 15))
while kill -0 "$pid" 2>/dev/null && (( SECONDS < deadline )); do sleep 1; done
if kill -0 "$pid" 2>/dev/null; then
echo "[WARN] $label did not stop gracefully; sending KILL"
kill -KILL "$pid" 2>/dev/null || true
fi
}
stop_service_port_listeners() {
local service="$1" port pid found=0
port="$(service_port "$service")"
while IFS= read -r pid; do
[[ -n "$pid" ]] || continue
found=1
stop_pid "$pid" "stale $service listener on port $port"
done < <(port_pids "$port")
if [[ "$found" == 1 ]]; then
rm -f "$(pid_file "$service")"
fi
}
stop_stale_project_processes() {
local pid cmd
while IFS= read -r line; do
pid="${line%% *}"
cmd="${line#* }"
[[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] || continue
[[ "$pid" == "$$" || "$pid" == "$BASHPID" ]] && continue
case "$cmd" in
*"$PROJECT_DIR"*"tsx"*"watch src/infrastructure/http/server.ts"*|\
*"$PROJECT_DIR"*"node_modules/tsx/dist/cli.mjs watch src/infrastructure/http/server.ts"*|\
*"$PROJECT_DIR"*"next start"*|\
*"$PROJECT_DIR"*"node_modules/next/dist/bin/next start"*)
stop_pid "$pid" "stale project process"
;;
esac
done < <(ps -axo pid=,command= 2>/dev/null | sed 's/^ *//')
}
clear_stale_deployments() {
echo '[INFO] Clearing old service deployments from managed ports...'
stop_stale_project_processes
local service
for service in "${SERVICES[@]}"; do
stop_service_port_listeners "$service"
done
}
assert_port_available() { assert_port_available() {
local service="$1" port existing managed local service="$1" port existing managed
port="$(service_port "$service")" port="$(service_port "$service")"
@@ -301,11 +364,8 @@ spawn_service() {
start_all() { start_all() {
ensure_env ensure_env
clear_stale_deployments
for service in "${SERVICES[@]}"; do for service in "${SERVICES[@]}"; do
if is_running "$service"; then
echo "[FAIL] $service is already managed in $MODE mode; use restart" >&2
exit 1
fi
rm -f "$(pid_file "$service")" rm -f "$(pid_file "$service")"
assert_port_available "$service" assert_port_available "$service"
done done
@@ -320,24 +380,9 @@ start_all() {
} }
stop_service() { stop_service() {
local service="$1" pid deadline local service="$1" pid
pid="$(read_pid "$service")" pid="$(read_pid "$service")"
if [[ -z "$pid" ]]; then stop_pid "$pid" "$service"
rm -f "$(pid_file "$service")"
return
fi
if ! kill -0 "$pid" 2>/dev/null; then
rm -f "$(pid_file "$service")"
return
fi
echo "[INFO] Stopping $service (PID $pid)..."
kill -TERM "$pid" 2>/dev/null || true
deadline=$((SECONDS + 15))
while kill -0 "$pid" 2>/dev/null && (( SECONDS < deadline )); do sleep 1; done
if kill -0 "$pid" 2>/dev/null; then
echo "[WARN] $service did not stop gracefully; sending KILL"
kill -KILL "$pid" 2>/dev/null || true
fi
rm -f "$(pid_file "$service")" rm -f "$(pid_file "$service")"
} }