Files
ss-tools/build.sh
busya 7c85552132 feat(ui): add chat-driven dataset review flow
Move dataset review clarification into the assistant workspace and
rework the review page into a chat-centric layout with execution rails.

Add session-scoped assistant actions for mappings, semantic fields,
and SQL preview generation. Introduce optimistic locking for dataset
review mutations, propagate session versions through API responses,
and mask imported filter values before assistant exposure.

Refresh tests, i18n, and spec artifacts to match the new workflow.

BREAKING CHANGE: dataset review mutation endpoints now require the
X-Session-Version header, and clarification is no longer handled
through ClarificationDialog-based flows
2026-03-26 13:33:12 +03:00

126 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# [DEF:build:Module]
# @PURPOSE: Utility script for build
# @COMPLEXITY: 1
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
BACKEND_ENV_FILE="$SCRIPT_DIR/backend/.env"
PROFILE="${1:-current}"
case "$PROFILE" in
master)
PROFILE_ENV_FILE="$SCRIPT_DIR/.env.master"
PROJECT_NAME="ss-tools-master"
;;
current)
PROFILE_ENV_FILE="$SCRIPT_DIR/.env.current"
PROJECT_NAME="ss-tools-current"
;;
*)
echo "Error: unknown profile '$PROFILE'. Use one of: master, current."
exit 1
;;
esac
if ! command -v docker >/dev/null 2>&1; then
echo "Error: docker is not installed or not in PATH."
exit 1
fi
if docker compose version >/dev/null 2>&1; then
COMPOSE_CMD=(docker compose)
elif command -v docker-compose >/dev/null 2>&1; then
COMPOSE_CMD=(docker-compose)
else
echo "Error: docker compose is not available."
exit 1
fi
ensure_backend_encryption_key() {
if command -v python3 >/dev/null 2>&1; then
python3 - "$BACKEND_ENV_FILE" <<'PY'
import base64
import os
import sys
from pathlib import Path
from typing import List, Optional
def is_valid_fernet_key(raw_value: str) -> bool:
value = raw_value.strip()
if not value:
return False
try:
decoded = base64.urlsafe_b64decode(value.encode())
except Exception:
return False
return len(decoded) == 32
def generate_fernet_key() -> str:
return base64.urlsafe_b64encode(os.urandom(32)).decode()
env_path = Path(sys.argv[1])
env_path.parent.mkdir(parents=True, exist_ok=True)
existing_lines: List[str] = []
existing_key: Optional[str] = None
if env_path.exists():
existing_lines = env_path.read_text(encoding="utf-8").splitlines()
for line in existing_lines:
if line.startswith("ENCRYPTION_KEY="):
candidate = line.partition("=")[2].strip()
if is_valid_fernet_key(candidate):
existing_key = candidate
break
if existing_key is None:
generated_key = generate_fernet_key()
filtered_lines = [line for line in existing_lines if not line.startswith("ENCRYPTION_KEY=")]
filtered_lines.append(f"ENCRYPTION_KEY={generated_key}")
env_path.write_text("\n".join(filtered_lines) + "\n", encoding="utf-8")
print(f"[build] ENCRYPTION_KEY ensured in {env_path}")
else:
print(f"[build] Existing ENCRYPTION_KEY reused from {env_path}")
PY
return
fi
echo "Error: python3 is required to generate backend/.env with ENCRYPTION_KEY."
exit 1
}
ensure_backend_encryption_key
COMPOSE_ARGS=(-p "$PROJECT_NAME")
if [[ -f "$PROFILE_ENV_FILE" ]]; then
COMPOSE_ARGS+=(--env-file "$PROFILE_ENV_FILE")
else
echo "[build] Warning: profile env file not found at $PROFILE_ENV_FILE, using compose defaults."
fi
echo "[build] Profile: $PROFILE (project: $PROJECT_NAME)"
if [[ -f "$PROFILE_ENV_FILE" ]]; then
echo "[build] Env file: $PROFILE_ENV_FILE"
fi
echo "[1/2] Building project images..."
"${COMPOSE_CMD[@]}" "${COMPOSE_ARGS[@]}" build
echo "[2/2] Starting Docker services..."
"${COMPOSE_CMD[@]}" "${COMPOSE_ARGS[@]}" up -d
echo "Done. Services are running."
echo "Use '${COMPOSE_CMD[*]} ${COMPOSE_ARGS[*]} ps' to check status and '${COMPOSE_CMD[*]} ${COMPOSE_ARGS[*]} logs -f' to stream logs."
# [/DEF:build:Module]