fix(api): allow nest build of program-settings and cleaner replica --check
Cast stored JSON through asSettingsArray so tsc accepts the snapshot payload, and strip Prisma ?schema= from DATABASE_URL before psql. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
# Copy to deploy/replicas.env on the publisher host (gitignored — holds passwords).
|
# Copy to deploy/replicas.env on the publisher host (gitignored — holds passwords).
|
||||||
#
|
#
|
||||||
# Every logical-replication subscriber of superadmin_pub, space/comma/newline separated.
|
# One DSN per line (or comma). Do not put spaces between URLs.
|
||||||
|
# Prefer URI form. Password must not contain @ : / # ? — or URL-encode it.
|
||||||
|
# Keyword form (host=...) is OK only because the script splits on newlines, not spaces.
|
||||||
# The user must be able to run ALTER TABLE (table owner or superuser).
|
# The user must be able to run ALTER TABLE (table owner or superuser).
|
||||||
REPLICA_DSNS="postgresql://USER:PASSWORD@SLAVE_1_IP:5433/superadmin
|
REPLICA_DSNS="postgresql://USER:PASSWORD@SLAVE_1_IP:5433/superadmin
|
||||||
postgresql://USER:PASSWORD@SLAVE_2_IP:5432/superadmin"
|
postgresql://USER:PASSWORD@SLAVE_2_IP:5432/superadmin"
|
||||||
|
|||||||
@@ -47,7 +47,10 @@ if [[ -z "${DATABASE_URL:-}" && -f "$API_DIR/.env" ]]; then
|
|||||||
set -a && source "$API_DIR/.env" && set +a
|
set -a && source "$API_DIR/.env" && set +a
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -r -a REPLICAS <<< "$(tr ',\n' ' ' <<< "$REPLICA_DSNS")"
|
# One DSN per line or comma (NOT spaces — keyword conninfo has spaces).
|
||||||
|
mapfile -t REPLICAS < <(
|
||||||
|
printf '%s\n' "$REPLICA_DSNS" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$'
|
||||||
|
)
|
||||||
|
|
||||||
# psql would otherwise swallow the loop input it is called from
|
# psql would otherwise swallow the loop input it is called from
|
||||||
run_psql() {
|
run_psql() {
|
||||||
@@ -56,7 +59,16 @@ run_psql() {
|
|||||||
|
|
||||||
# host:port/db only — DSNs carry passwords
|
# host:port/db only — DSNs carry passwords
|
||||||
label() {
|
label() {
|
||||||
sed -E 's#^[a-z]+://([^@]*@)?##; s#\?.*$##' <<< "$1"
|
local dsn="$1"
|
||||||
|
if [[ "$dsn" == *"://"* ]]; then
|
||||||
|
sed -E 's#^[a-z]+://([^@]*@)?##; s#\?.*$##' <<< "$dsn"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local host port db
|
||||||
|
host="$(sed -nE 's/.*host=([^ ]+).*/\1/p' <<< "$dsn")"
|
||||||
|
port="$(sed -nE 's/.*port=([^ ]+).*/\1/p' <<< "$dsn")"
|
||||||
|
db="$(sed -nE 's/.*dbname=([^ ]+).*/\1/p' <<< "$dsn")"
|
||||||
|
echo "${host:-?}:${port:-5432}/${db:-?}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# every list feeding comm is sorted with the same collation
|
# every list feeding comm is sorted with the same collation
|
||||||
@@ -97,13 +109,19 @@ apply_migration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
column_fingerprint() {
|
column_fingerprint() {
|
||||||
run_psql "$1" -v ON_ERROR_STOP=1 -At -c "
|
run_psql "$(libpq_dsn "$1")" -v ON_ERROR_STOP=1 -At -c "
|
||||||
SELECT table_name || '.' || column_name
|
SELECT table_name || '.' || column_name
|
||||||
FROM information_schema.columns
|
FROM information_schema.columns
|
||||||
WHERE table_schema = 'public'
|
WHERE table_schema = 'public'
|
||||||
AND table_name NOT IN ('_replica_ddl_applied')" | LC_ALL=C sort
|
AND table_name NOT IN ('_replica_ddl_applied')" | LC_ALL=C sort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Prisma DATABASE_URL uses ?schema=public; libpq rejects that query param.
|
||||||
|
libpq_dsn() {
|
||||||
|
local u="$1"
|
||||||
|
echo "${u%%\?*}"
|
||||||
|
}
|
||||||
|
|
||||||
if [[ "$MODE" == "--check" ]]; then
|
if [[ "$MODE" == "--check" ]]; then
|
||||||
for dsn in "${REPLICAS[@]}"; do
|
for dsn in "${REPLICAS[@]}"; do
|
||||||
echo "== $(label "$dsn")"
|
echo "== $(label "$dsn")"
|
||||||
|
|||||||
@@ -144,7 +144,9 @@ export class ProgramSettingsService {
|
|||||||
importedAt: '',
|
importedAt: '',
|
||||||
source: 'khanegi_admin',
|
source: 'khanegi_admin',
|
||||||
apiBase: '',
|
apiBase: '',
|
||||||
items: raw.filter((row) => this.isSystemSetting(row as ProgramSettingRow)),
|
items: this.asSettingsArray(raw).filter((row) =>
|
||||||
|
this.isSystemSetting(row),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user