# Zindex - Living architecture diagram. Scans the repository on a daily
# schedule (and on every push to main) and patches the persisted scene with
# whatever has been added, removed, or rewired since the last run. Over months
# the revision history doubles as an architecture changelog.
#
# Drop into .github/workflows/zindex-architecture.yml.

name: Zindex - Living architecture docs

on:
  push:
    branches: [main]
  schedule:
    - cron: "0 4 * * *"   # Daily 04:00 UTC safety net
  workflow_dispatch:

permissions:
  contents: write     # commit the rendered SVG into docs/architecture.svg
  pull-requests: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  # Don't cancel main-branch runs - let them queue so the architecture
  # changelog stays linear.
  cancel-in-progress: false

env:
  ZINDEX_API_BASE: https://api.zindex.ai

jobs:
  sync-architecture:
    runs-on: ubuntu-latest
    # Don't recurse if we just pushed the rendered SVG ourselves.
    if: github.actor != 'github-actions[bot]'
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0    # need full history for the auto-commit

      # 1. Scan the repo. Author scripts/scan-architecture.mjs against your
      #    monorepo conventions: services/*/Dockerfile, apps/*/package.json,
      #    detector regexes for databases (postgres URL strings), queues
      #    (Kafka topic names), external SDK imports.
      - name: Scan repository for components and edges
        run: |
          mkdir -p out
          node scripts/scan-architecture.mjs > out/architecture.json

      - name: Capture current revision
        id: prev_rev
        env:
          ZINDEX_API_KEY: ${{ secrets.ZINDEX_API_KEY }}
          ZINDEX_SCENE_ID: ${{ secrets.ZINDEX_SCENE_ID }}
        run: |
          echo "rev=$(curl -fsSL -H "Authorization: Bearer $ZINDEX_API_KEY" \
            "$ZINDEX_API_BASE/v1/scenes/$ZINDEX_SCENE_ID" | jq -r '.revision')" >> "$GITHUB_OUTPUT"

      - name: Compute applyOps batch
        run: node scripts/architecture-to-ops.mjs out/architecture.json > out/ops.json

      - name: Apply ops
        id: apply
        env:
          ZINDEX_API_KEY: ${{ secrets.ZINDEX_API_KEY }}
          ZINDEX_SCENE_ID: ${{ secrets.ZINDEX_SCENE_ID }}
        run: |
          RESP=$(curl -fsSL -X POST \
            -H "Authorization: Bearer $ZINDEX_API_KEY" \
            -H "Content-Type: application/json" \
            --data-binary @out/ops.json \
            "$ZINDEX_API_BASE/v1/scenes/$ZINDEX_SCENE_ID/ops")
          echo "rev=$(echo "$RESP" | jq -r '.revision')" >> "$GITHUB_OUTPUT"
          echo "applied=$(echo "$RESP" | jq -r '.applied')" >> "$GITHUB_OUTPUT"

      - name: Render
        env:
          ZINDEX_API_KEY: ${{ secrets.ZINDEX_API_KEY }}
          ZINDEX_SCENE_ID: ${{ secrets.ZINDEX_SCENE_ID }}
        run: |
          mkdir -p docs/architecture
          curl -fsSL -X POST \
            -H "Authorization: Bearer $ZINDEX_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{"format":"svg","theme":"clean"}' \
            "$ZINDEX_API_BASE/v1/scenes/$ZINDEX_SCENE_ID/render" \
            | jq -r '.output.content' > docs/architecture/diagram.svg

      # 2. Commit the rendered SVG back into the repo so the diagram lives
      #    next to the code it describes (and the README can embed a stable
      #    raw URL). Skip the commit if nothing changed - git itself is the
      #    no-op detector.
      - name: Commit rendered diagram
        if: steps.apply.outputs.applied != '0'
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add docs/architecture/diagram.svg
          if git diff --cached --quiet; then
            echo "::notice::No diagram changes to commit."
          else
            git commit -m "chore(docs): refresh architecture diagram (rev ${{ steps.apply.outputs.rev }})"
            git push
          fi

      # 3. Weekly digest: if today is Monday, post a short summary to Slack
      #    listing components added / removed / rewired in the past week.
      #    Implement scripts/post-weekly-digest.mjs against your Slack webhook
      #    and SCENE_ID - call dsp_diff_scene with from = revision a week ago.
      - name: Weekly architecture digest (Mondays)
        if: github.event.schedule == '0 4 * * *' && env.IS_MONDAY == '1'
        env:
          IS_MONDAY: ${{ format(github.event.schedule, '') == '' && (fromJSON('false')) || '1' }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          ZINDEX_API_KEY: ${{ secrets.ZINDEX_API_KEY }}
          ZINDEX_SCENE_ID: ${{ secrets.ZINDEX_SCENE_ID }}
        run: node scripts/post-weekly-digest.mjs
