Ця сторінка ще не перекладена українською. Показано англійську версію. Переглянути англійською

Міжпроєктна звітність

Агрегуйте та аналізуйте дані по кількох проєктах ACC для портфельних інсайтів.

Огляд робочого процесу

Кілька проєктів
Проєкт A
Проєкт B
Проєкт C
Збір даних
Проблеми
RFI
Подачі
Чек-листи
Агрегація
Об’єднання даних
Нормалізація полів
Додавання контексту проєкту
Звіти
Портфельне зведення
Міжпроєктні метрики
Дашборд для керівництва
Проєкти → Дані → Агрегація → Звіти

Підхід через CLI

Отримання всіх проєктів

HUB_ID="b.hub-id"

# List all projects
raps project list "$HUB_ID" --output json > projects.json

# Filter active construction projects
cat projects.json | jq '[.[] | select(.status == "active")]' > active-projects.json

Агрегація проблем по проєктах

# Collect issues from all projects
echo '[]' > all-issues.json

jq -r '.[].id' active-projects.json | while read proj_id; do
  PROJ_NAME=$(jq -r ".[] | select(.id == \"$proj_id\") | .name" active-projects.json)

  raps acc issue list "$proj_id" --output json 2>/dev/null | \
    jq --arg proj "$proj_id" --arg name "$PROJ_NAME" \
    '[.[] | . + {projectId: $proj, projectName: $name}]' >> temp-issues.json
done

# Combine all
cat temp-issues.json | jq -s 'flatten' > all-issues.json
rm temp-issues.json

Портфельне зведення

# Generate portfolio-wide summary
cat all-issues.json | jq '
  {
    totalIssues: length,
    openIssues: [.[] | select(.status == "open")] | length,
    byProject: (group_by(.projectName) | map({
      project: .[0].projectName,
      total: length,
      open: [.[] | select(.status == "open")] | length
    })),
    byPriority: (group_by(.priority) | map({
      priority: .[0].priority,
      count: length
    }))
  }'

Порівняння проєктів

# Compare metrics across projects
echo "# Portfolio Comparison" > portfolio-report.md
echo "" >> portfolio-report.md

jq -r '.[].id' active-projects.json | while read proj_id; do
  PROJ_NAME=$(jq -r ".[] | select(.id == \"$proj_id\") | .name" active-projects.json)

  # Get metrics
  ISSUES=$(jq --arg p "$proj_id" '[.[] | select(.projectId == $p)] | length' all-issues.json)
  OPEN=$(jq --arg p "$proj_id" '[.[] | select(.projectId == $p and .status == "open")] | length' all-issues.json)

  echo "## $PROJ_NAME" >> portfolio-report.md
  echo "- Total Issues: $ISSUES" >> portfolio-report.md
  echo "- Open Issues: $OPEN" >> portfolio-report.md
  echo "" >> portfolio-report.md
done

CI/CD-конвеєр

# .github/workflows/portfolio-report.yml
name: Portfolio Reporting

on:
  schedule:
    - cron: '0 6 * * 1'  # Weekly on Monday
  workflow_dispatch:

env:
  HUB_ID: ${{ secrets.ACC_HUB_ID }}

jobs:
  portfolio-report:
    runs-on: ubuntu-latest
    steps:
      - name: Install RAPS
        run: cargo install raps

      - name: Authenticate
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
          APS_ACCESS_TOKEN: ${{ secrets.APS_ACCESS_TOKEN }}
          APS_REFRESH_TOKEN: ${{ secrets.APS_REFRESH_TOKEN }}
        run: raps auth login --token "$APS_ACCESS_TOKEN" --refresh-token "$APS_REFRESH_TOKEN" --non-interactive

      - name: Get all projects
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
        run: |
          mkdir -p ./portfolio

          raps project list "$HUB_ID" --output json > ./portfolio/projects.json
          jq '[.[] | select(.status == "active")]' ./portfolio/projects.json > ./portfolio/active.json

      - name: Collect cross-project data
        env:
          APS_CLIENT_ID: ${{ secrets.APS_CLIENT_ID }}
          APS_CLIENT_SECRET: ${{ secrets.APS_CLIENT_SECRET }}
        run: |
          echo '[]' > ./portfolio/all-issues.json
          echo '[]' > ./portfolio/all-rfis.json
          echo '[]' > ./portfolio/all-submittals.json

          jq -r '.[].id' ./portfolio/active.json | while read proj_id; do
            NAME=$(jq -r ".[] | select(.id == \"$proj_id\") | .name" ./portfolio/active.json)

            # Issues
            raps acc issue list "$proj_id" --output json 2>/dev/null | \
              jq --arg p "$proj_id" --arg n "$NAME" '[.[] | . + {projectId: $p, projectName: $n}]' >> ./portfolio/temp-issues.json || true

            # RFIs
            raps acc rfi list "$proj_id" --output json 2>/dev/null | \
              jq --arg p "$proj_id" --arg n "$NAME" '[.[] | . + {projectId: $p, projectName: $n}]' >> ./portfolio/temp-rfis.json || true

            # Submittals
            raps acc submittal list "$proj_id" --output json 2>/dev/null | \
              jq --arg p "$proj_id" --arg n "$NAME" '[.[] | . + {projectId: $p, projectName: $n}]' >> ./portfolio/temp-submittals.json || true
          done

          # Combine files
          cat ./portfolio/temp-issues.json 2>/dev/null | jq -s 'flatten' > ./portfolio/all-issues.json || echo '[]' > ./portfolio/all-issues.json
          cat ./portfolio/temp-rfis.json 2>/dev/null | jq -s 'flatten' > ./portfolio/all-rfis.json || echo '[]' > ./portfolio/all-rfis.json
          cat ./portfolio/temp-submittals.json 2>/dev/null | jq -s 'flatten' > ./portfolio/all-submittals.json || echo '[]' > ./portfolio/all-submittals.json

      - name: Generate portfolio report
        run: |
          echo "# Portfolio Report" > ./portfolio/report.md
          echo "Generated: $(date)" >> ./portfolio/report.md
          echo "" >> ./portfolio/report.md

          PROJECTS=$(jq 'length' ./portfolio/active.json)
          echo "## Overview" >> ./portfolio/report.md
          echo "Active Projects: $PROJECTS" >> ./portfolio/report.md
          echo "" >> ./portfolio/report.md

          # Issues summary
          echo "## Issues Summary" >> ./portfolio/report.md
          TOTAL_ISSUES=$(jq 'length' ./portfolio/all-issues.json)
          OPEN_ISSUES=$(jq '[.[] | select(.status == "open")] | length' ./portfolio/all-issues.json)
          echo "- Total: $TOTAL_ISSUES" >> ./portfolio/report.md
          echo "- Open: $OPEN_ISSUES" >> ./portfolio/report.md
          echo "" >> ./portfolio/report.md

          # By project table
          echo "## By Project" >> ./portfolio/report.md
          echo "| Project | Issues | Open | RFIs | Submittals |" >> ./portfolio/report.md
          echo "|---------|--------|------|------|------------|" >> ./portfolio/report.md

          jq -r '.[].name' ./portfolio/active.json | while read name; do
            ISSUES=$(jq --arg n "$name" '[.[] | select(.projectName == $n)] | length' ./portfolio/all-issues.json)
            OPEN=$(jq --arg n "$name" '[.[] | select(.projectName == $n and .status == "open")] | length' ./portfolio/all-issues.json)
            RFIS=$(jq --arg n "$name" '[.[] | select(.projectName == $n)] | length' ./portfolio/all-rfis.json)
            SUBS=$(jq --arg n "$name" '[.[] | select(.projectName == $n)] | length' ./portfolio/all-submittals.json)
            echo "| $name | $ISSUES | $OPEN | $RFIS | $SUBS |" >> ./portfolio/report.md
          done

      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: portfolio-report
          path: ./portfolio/

Потік конвеєра

Щотижня, понеділок
Розклад
Збір даних
Список проєктів
Отримання проблем/RFI/подач
Агрегація
Об’єднання даних
Додавання контексту проєкту
Звіти
report.md
all-issues.json
портфельні метрики

Інтеграція з MCP

Огляд портфеля

User: "Give me a summary across all our active construction projects"
КористувачAI-асистентRAPS MCPACC Cloud
Корист.Зведення по портфелюAI
AIaps_hub_list()MCP
AIaps_project_list(hub_id)MCP
Цикл: Для кожного проєкту
AIaps_acc_issue_list, rfi_list, submittal_listACC
AI: Агрегація та аналіз
AIПортфельний дашбордКорист.

Відповідь AI:

Зведення по портфелю - 5 активних проєктів

ПроєктПроблемиRFIПодачіСтатус
Main Street Tower45 (12 відкр.)2389За графіком
Riverside Complex32 (8 відкр.)1867Незначні затримки
Tech Campus Ph228 (5 відкр.)1245За графіком
Harbor View56 (18 відкр.)31102Під загрозою
Metro Station19 (3 відкр.)834За графіком

Підсумки по портфелю:

  • Всього відкритих проблем: 46
  • Всього відкритих RFI: 28
  • Подач в очікуванні: 45

Увага: Harbor View має високу кількість відкритих проблем.

Порівняння проєктів

User: "Compare issue resolution rates across projects"

Відповідь AI:

Порівняння швидкості вирішення проблем:

ПроєктСтвореноВирішеноЧасткаСер. днів
Tech Campus Ph2454089%5.2
Metro Station282486%6.1
Main Street Tower786583%7.4
Riverside Complex524281%8.2
Harbor View895865%12.3

Висновок: Harbor View має значно нижчу швидкість вирішення та довший час обробки. Рекомендується збільшити ресурси на управління проблемами.


Запити для дашборду

Критичні елементи по портфелю

cat all-issues.json | jq '
  [.[] | select(.priority == "critical" and .status == "open")] |
  group_by(.projectName) |
  map({project: .[0].projectName, criticalOpen: length, issues: [.[] | .title]})'

Зведення прострочених елементів

TODAY=$(date +%Y-%m-%d)

echo "Overdue items by project:"
for type in issues rfis submittals; do
  echo "=== $type ==="
  cat "./portfolio/all-${type}.json" | jq --arg today "$TODAY" '
    [.[] | select(.dueDate != null and .dueDate < $today and .status == "open")] |
    group_by(.projectName) |
    map({project: .[0].projectName, overdue: length})'
done

Тижневий тренд

# Issues created per week across portfolio
cat all-issues.json | jq '
  group_by(.createdAt[:10] | strptime("%Y-%m-%d") | strftime("%Y-W%V")) |
  map({week: .[0].createdAt[:10] | strptime("%Y-%m-%d") | strftime("%Y-W%V"), created: length}) |
  sort_by(.week)'

Пов’язане