#!/usr/bin/env bash # Prepare strongsuit_phx to run against the same database the Remix app uses. # # Three things stand between a checkout and a working service, none of them a code change: # # 1. config/dev.exs ends with `import_config "dev.secret.exs"`, so mix won't boot without that # gitignored file. run-app's elixir setup seeds it from dev.secret.exs.example, which carries # no Repo override — so this script OVERWRITES rather than skipping when it already exists. # 2. dev.exs points Ecto at the database "postgres", but the two services share ONE database and # the toolkit seeds "strongsuit". Left alone, phx 401s every request from an empty user table. # 3. Prisma owns the schema, so the tables exist but Ecto's schema_migrations is empty. The # migrations are recorded as applied rather than run; otherwise the dev-only CheckRepoStatus # plug 503s every request. # # Idempotent. Run after the strongsuit-app setup, which creates and seeds the database. set -euo pipefail REPO_DIR="${1:-/workspace/repos/strongsuit_phx}" DB="${PGDATABASE:-strongsuit}" cat > "$REPO_DIR/config/dev.secret.exs" <<'ELIXIR' # Local development config for the offline toolkit container. Generated by # explore/scripts/seed/setup-strongsuit-phx.sh; gitignored, so not a change to the repo. # Every credential here is an inert dummy: none of these services is reachable offline. import Config # The Remix app and this service share one database, and the toolkit seeds "strongsuit". config :scrubbed011_phx, Scrubbed011Phx.Repo, database: "strongsuit" # The port both sides of PHX_DOMAIN agree on. dev.exs hardcodes 4000, which this toolkit already # publishes for another estate, so the caller passes its own. # Only the port is overridden here: Config deep-merges keyword lists, so a `watchers: []` would # merge INTO dev.exs's list rather than replace it. The esbuild watcher therefore still runs and # still fails on the missing assets/vendor/topbar -- once, without restarting, and the endpoint # serves throughout. The API the Remix app calls needs no bundle. config :scrubbed011_phx, Scrubbed011PhxWeb.Endpoint, http: [ip: {0, 0, 0, 0}, port: String.to_integer(System.get_env("PHX_PORT") || "4201")] config :scrubbed011_phx, Scrubbed011Phx.ApiClients.Cio, host: "https://track.customer.io", site_id: "dummy", api_key: "dummy" config :scrubbed011_phx, Scrubbed011Phx.ApiClients.Twilio, account_sid: "dummy", auth_token: "dummy", messaging_service_sid: "dummy" config :scrubbed011_phx, Scrubbed011Phx.TalkJsMessages, twilio_from_number: "+15005550006" config :scrubbed011_phx, Scrubbed011PhxWeb.Plugs.TalkJsWebhook, secret_key: "dummy" config :langchain, :anthropic_key, "dummy" config :scrubbed011_phx, Scrubbed011Phx.ApiClients.Talkjs, app_id: "dummy", secret_key: "dummy" config :scrubbed011_phx, Scrubbed011Phx.ApiClients.CronofyApi, host: "https://api.cronofy.com", client_id: "dummy", client_secret: "dummy" # The Remix app, as this service sees it: same container, its own port. config :scrubbed011_phx, Scrubbed011Phx.ApiClients.Scrubbed011App, host: "http://localhost:3000", ss_app_api_key: "dummy" ELIXIR echo " wrote config/dev.secret.exs" cd "$REPO_DIR" mix local.hex --force >/dev/null 2>&1 || true mix local.rebar --force >/dev/null 2>&1 || true MIX_ENV=dev mix deps.get # assets.setup only downloads the esbuild/tailwind binaries, which has to happen while there is # still a network; it does NOT build a bundle (see the watchers note above). NOT `mix setup`: # that alias runs ecto.setup, and Prisma owns this schema. MIX_ENV=dev mix assets.setup MIX_ENV=dev mix compile # Record the migrations Prisma has already applied the equivalent of. Skipped when the database # isn't there yet, which is what `run-app strongsuit_phx` on its own looks like — the app's own # setup is what creates and seeds it. if ! PGPASSWORD="${PGPASSWORD:-postgres}" psql -h "${PGHOST:-localhost}" -U "${PGUSER:-postgres}" \ -d "$DB" -tAc 'select 1' >/dev/null 2>&1; then echo " database \"$DB\" not ready — run \`run-app strongsuit-app\`, which creates it and" echo " starts this service alongside the app." exit 0 fi versions=$(ls priv/repo/migrations | sed 's/_.*//' | awk '{printf "(%s, now()),", $1}' | sed 's/,$//') if [ -n "$versions" ]; then PGPASSWORD="${PGPASSWORD:-postgres}" psql -h "${PGHOST:-localhost}" -U "${PGUSER:-postgres}" \ -d "$DB" -v ON_ERROR_STOP=1 -q \ -c "create table if not exists schema_migrations ( version bigint primary key, inserted_at timestamp(0));" \ -c "insert into schema_migrations (version, inserted_at) values $versions on conflict (version) do nothing;" echo " baselined $(ls priv/repo/migrations | wc -l | tr -d ' ') migrations in schema_migrations" fi echo "strongsuit_phx ready — start it with: MIX_ENV=dev mix phx.server (listens on :${PHX_PORT:-4201})" echo " its own HTML pages render unstyled, and phx.log carries one esbuild error for the" echo " missing assets/vendor/topbar -- neither affects the JSON API the app uses"