Skip to content

Feature/user activity tracker#2

Open
DhirenMhatre wants to merge 9 commits into
feature/distributed-code-cachingfrom
feature/user-activity-tracker
Open

Feature/user activity tracker#2
DhirenMhatre wants to merge 9 commits into
feature/distributed-code-cachingfrom
feature/user-activity-tracker

Conversation

@DhirenMhatre

Copy link
Copy Markdown

No description provided.

@DhirenMhatre

Copy link
Copy Markdown
Author

@codity review

@codity-dev

codity-dev Bot commented Feb 4, 2026

Copy link
Copy Markdown

PR review started! Estimated time: 5-10 minutes.
Using default review instructions (no custom configuration found)

💡 Learn More

📊 View Analytics Dashboard

Ask Codity questions:
Mention @codity {your question} in a comment to get answers about the code.

Trigger a manual review:
Comment @codity review on a PR or MR.

Generate unit tests:
Comment /generate-tests to auto-generate tests for Go, Python, Ruby, JavaScript, TypeScript, and Java files.

Run security scan again:
Comment /security-scan to run SAST and dependency vulnerability scans for all major languages in your repo.

View Full Docs

@codity-dev

codity-dev Bot commented Feb 4, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Introduced cross-service user activity tracking and analytics (Go tracker, JS dashboard, Python analyzer, Ruby reporter) to deliver insights like trends, engagement, and anomalies.
  • Added CI pipelines (GitHub Actions for Java; Azure Pipelines for Go/Python/Ruby/JS) to speed up PR validation.
  • Established TypeScript build config and test scaffolding to support new JS analytics components.

Key Changes by Area

  • Go Service: Added per-user activity tracker supporting logging, stats, date-range queries, and deletion.
  • JS Service: Enhanced ActivityDashboard with date-range filtering, aggregation/top actions, engagement scoring, session averages, and period grouping.
  • JS Service: Added tsconfig and package updates to enable TypeScript build and testing.
  • Python Service: Introduced ActivityAnalyzer for pattern detection, anomaly detection, and user scoring.
  • Ruby Service: Added ActivityReporter for reports, timelines, exports, and user comparisons; included minimal rails_helper for specs.
  • CI/CD: Created GitHub Actions workflow for Java tests and Azure Pipelines quick-test pipeline for multi-language services.

Files Changed

File Changes Summary
.github/workflows/java-tests.yml Add GitHub Actions workflow to run Maven/Gradle tests for Java projects on PRs.
azure-pipelines.yml Add Azure Pipelines config to run quick tests across Go, Python, Ruby, and JS services.
go-service/internal/activity/tracker.go Implement user activity tracker with logging, stats, date-range queries, and deletion operations.
js-service/tests/.gitkeep Add placeholder to ensure test directory is tracked.
js-service/package.json Update scripts/dependencies to support ActivityDashboard and TypeScript build/testing.
js-service/src/activity-dashboard.ts Implement ActivityDashboard with summaries, trends, filtering, aggregation/top actions, scoring, session averages, and period grouping.
js-service/tsconfig.json Add TypeScript configuration for building JS analytics components.
python-service/src/activity_analyzer.py Add ActivityAnalyzer for pattern/anomaly detection and user engagement scoring.
ruby-service/app/activity_reporter.rb Add ActivityReporter for reports, timelines, exports, and user comparisons.
ruby-service/spec/rails_helper.rb Add minimal spec helper to support tests in a non-Rails setup.

Potential Impact

  • Possible performance overhead during analytics calculations and increased storage from activity logs.
  • Privacy/compliance considerations for user activity logging and exported reports.
  • No significant breaking changes.

Review Focus Areas

  • Accuracy and efficiency of date-range filtering, aggregation, and period grouping across services.
  • Robustness of anomaly detection thresholds and scoring in python-service/src/activity_analyzer.py.
  • Data retention, PII handling, and deletion semantics in go-service/internal/activity/tracker.go and report exports.

@codity-dev

codity-dev Bot commented Feb 4, 2026

Copy link
Copy Markdown

Workflow Diagrams

Automatically generated sequence diagrams showing the workflows in this PR

1. Service Integration Flow

Medium complexity • Components: Java Tests CI workflow, Azure Pipelines for multiple languages, Activity Tracker in Go service

sequenceDiagram
    title PR: Integration of Java Tests CI and Azure Pipelines for Multi-Language Support

    participant Client
    participant GitHubActions as GitHub Actions
    participant AzurePipelines as Azure Pipelines
    participant GoService as Go Service
    participant PythonService as Python Service
    participant RubyService as Ruby Service
    participant JavaService as Java Service
    participant JSService as JavaScript Service

    Client->>GitHubActions: Trigger PR
    GitHubActions->>JavaService: Run Java Tests
    JavaService->>GitHubActions: Return test results

    alt Java Tests Success
        GitHubActions->>AzurePipelines: Trigger Azure Pipeline
        AzurePipelines->>GoService: Run Go Tests
        GoService->>AzurePipelines: Return Go test results

        AzurePipelines->>PythonService: Run Python Tests
        PythonService->>AzurePipelines: Return Python test results

        AzurePipelines->>RubyService: Run Ruby Tests
        RubyService->>AzurePipelines: Return Ruby test results

        AzurePipelines->>JSService: Run JavaScript Tests
        JSService->>AzurePipelines: Return JavaScript test results
    else Java Tests Fail
        GitHubActions->>Client: Notify failure
    end

    note right of AzurePipelines: Each service runs tests based on the modified code
    note right of GoService: Go service tracks user activities
    note right of JSService: JavaScript service aggregates activity data
Loading

Note: Diagrams show detected patterns only. Complex workflows may require manual review.

Comment on lines +71 to +76
if filepath
File.write(filepath, json_data)
{ success: true, filepath: filepath, size: json_data.bytesize }
else
{ success: true, data: json_data }
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Unvalidated file path is written directly with File.write, allowing potential path traversal or overwriting arbitrary files if the filepath is user-controlled.

Code Suggestion or Comments
if filepath
      require 'fileutils'

      # Constrain writes to a dedicated, controlled directory
      safe_dir = File.expand_path('reports', Dir.pwd)
      FileUtils.mkdir_p(safe_dir)

      basename = File.basename(filepath.to_s)
      raise ArgumentError, 'Invalid filename' if basename.empty?

      target = File.join(safe_dir, basename)
      raise ArgumentError, 'Unsafe path' unless File.expand_path(target).start_with?(safe_dir)

      File.open(target, 'w', 0o640) { |f| f.write(json_data) }
      { success: true, filepath: target, size: json_data.bytesize }
    else
      { success: true, data: json_data }
    end
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 71-76
Issue Type: security-critical
Severity: critical

Issue Description:
Unvalidated file path is written directly with File.write, allowing potential path traversal or overwriting arbitrary files if the filepath is user-controlled.

Current Code:
    if filepath
      File.write(filepath, json_data)
      { success: true, filepath: filepath, size: json_data.bytesize }
    else
      { success: true, data: json_data }
    end

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +46 to +51
if first_ts and last_ts:
days_active = max((last_ts - first_ts).days, 1)
actions_per_day = total_actions / days_active
else:
actions_per_day = total_actions

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

Potential TypeError when subtracting timezone-aware and naive datetimes. If activities contain mixed timestamp types (aware vs naive), (last_ts - first_ts) can raise: 'can't subtract offset-naive and offset-aware datetimes'.

Code Suggestion or Comments
def _parse_timestamp(self, ts: Any) -> Optional[datetime]:
        if isinstance(ts, datetime):
            return ts if ts.tzinfo is not None else ts.replace(tzinfo=timezone.utc)

        if isinstance(ts, str):
            try:
                dt = datetime.fromisoformat(ts.replace('Z', '+00:00'))
                return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
            except (ValueError, AttributeError):
                pass

        return None
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 46-51
Issue Type: functional-high
Severity: high

Issue Description:
Potential TypeError when subtracting timezone-aware and naive datetimes. If activities contain mixed timestamp types (aware vs naive), (last_ts - first_ts) can raise: 'can't subtract offset-naive and offset-aware datetimes'.

Current Code:
        if first_ts and last_ts:
            days_active = max((last_ts - first_ts).days, 1)
            actions_per_day = total_actions / days_active
        else:
            actions_per_day = total_actions

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +78 to +83
timestamps.sort()
intervals = []
for i in range(1, len(timestamps)):
interval = (timestamps[i] - timestamps[i-1]).total_seconds()
intervals.append(interval)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

Sorting and subtracting datetimes may fail if timestamps are a mix of timezone-aware and naive objects, causing TypeError during sort or subtraction.

Code Suggestion or Comments
def _parse_timestamp(self, ts: Any) -> Optional[datetime]:
        if isinstance(ts, datetime):
            return ts if ts.tzinfo is not None else ts.replace(tzinfo=timezone.utc)

        if isinstance(ts, str):
            try:
                dt = datetime.fromisoformat(ts.replace('Z', '+00:00'))
                return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
            except (ValueError, AttributeError):
                pass

        return None
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 78-83
Issue Type: functional-high
Severity: high

Issue Description:
Sorting and subtracting datetimes may fail if timestamps are a mix of timezone-aware and naive objects, causing TypeError during sort or subtraction.

Current Code:
            timestamps.sort()
            intervals = []
            for i in range(1, len(timestamps)):
                interval = (timestamps[i] - timestamps[i-1]).total_seconds()
                intervals.append(interval)

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
# Test python-service
if [ -d "python-service" ]; then
cd python-service
pip install -r requirements.txt 2>/dev/null || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Ignoring pip installation errors and redirecting output to /dev/null can result in tests running without required dependencies and makes debugging difficult.

Code Suggestion or Comments
pip install -r requirements.txt
            if [ $? -ne 0 ]; then
              echo "Dependency installation failed" >&2
              exit 1
            fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 61-61
Issue Type: robustness-high
Severity: high

Issue Description:
Ignoring pip installation errors and redirecting output to /dev/null can result in tests running without required dependencies and makes debugging difficult.

Current Code:
            pip install -r requirements.txt 2>/dev/null || true

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +15 to +16
- name: Checkout code
uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

GitHub Action is referenced by a mutable version tag (v4). Unpinned actions can be tampered with if the tag is moved or compromised, leading to supply-chain execution of malicious code.

Code Suggestion or Comments
- name: Checkout code
      uses: actions/checkout@<commit-sha> # pinned commit for v4
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 15-16
Issue Type: security-high
Severity: high

Issue Description:
GitHub Action is referenced by a mutable version tag (v4). Unpinned actions can be tampered with if the tag is moved or compromised, leading to supply-chain execution of malicious code.

Current Code:
    - name: Checkout code
      uses: actions/checkout@v4

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +18 to +23
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Unpinned third-party action (actions/setup-java) referenced by a mutable tag (v4). This exposes the workflow to supply-chain risk if the tag changes unexpectedly.

Code Suggestion or Comments
- name: Set up Java
      uses: actions/setup-java@<commit-sha> # pinned commit for v4
      with:
        distribution: 'temurin'
        java-version: '17'
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 18-23
Issue Type: security-high
Severity: high

Issue Description:
Unpinned third-party action (actions/setup-java) referenced by a mutable tag (v4). This exposes the workflow to supply-chain risk if the tag changes unexpectedly.

Current Code:
    - name: Set up Java
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +24 to +41
- name: Run tests with Maven or Gradle
run: |
# Check for Maven
if [ -f "pom.xml" ]; then
echo "Found Maven project"
mvn test -B
# Check for Gradle
elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
echo "Found Gradle project"
if [ -f "gradlew" ]; then
chmod +x gradlew
./gradlew test
else
gradle test
fi
else
echo "No Maven or Gradle build file found"
exit 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

The workflow runs the Gradle wrapper from PRs without validating the wrapper JAR integrity, which can enable remote code execution if the wrapper files are tampered with. It also falls back to running system Gradle if the wrapper is missing, which bypasses wrapper validation.

Code Suggestion or Comments
- name: Validate Gradle Wrapper
      uses: gradle/wrapper-validation-action@<commit-sha> # pinned commit for v1

    - name: Run tests with Maven or Gradle
      run: |
        # Check for Maven
        if [ -f "pom.xml" ]; then
          echo "Found Maven project"
          mvn test -B
        # Check for Gradle
        elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
          echo "Found Gradle project"
          if [ -f "gradlew" ]; then
            chmod +x gradlew
            ./gradlew test
          else
            echo "Gradle wrapper not found; refusing to run system Gradle for security."
            exit 1
          fi
        else
          echo "No Maven or Gradle build file found"
          exit 1
        fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 24-41
Issue Type: security-high
Severity: high

Issue Description:
The workflow runs the Gradle wrapper from PRs without validating the wrapper JAR integrity, which can enable remote code execution if the wrapper files are tampered with. It also falls back to running system Gradle if the wrapper is missing, which bypasses wrapper validation.

Current Code:
    - name: Run tests with Maven or Gradle
      run: |
        # Check for Maven
        if [ -f "pom.xml" ]; then
          echo "Found Maven project"
          mvn test -B
        # Check for Gradle
        elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
          echo "Found Gradle project"
          if [ -f "gradlew" ]; then
            chmod +x gradlew
            ./gradlew test
          else
            gradle test
          fi
        else
          echo "No Maven or Gradle build file found"
          exit 1
        fi

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +155 to +157
func generateID(counter int) string {
return time.Now().Format("20060102150405") + "-" + string(rune(counter))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

generateID converts the integer counter to a single Unicode rune via string(rune(counter)), producing non-printable or unexpected characters instead of a decimal string. This can lead to unreadable IDs and potential downstream parsing/serialization issues.

Code Suggestion or Comments
import (
	"sort"
	"strconv"
	"sync"
	"time"
)

func generateID(counter int) string {
	return time.Now().Format("20060102150405") + "-" + strconv.Itoa(counter)
}
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 155-157
Issue Type: functional-high
Severity: high

Issue Description:
generateID converts the integer counter to a single Unicode rune via string(rune(counter)), producing non-printable or unexpected characters instead of a decimal string. This can lead to unreadable IDs and potential downstream parsing/serialization issues.

Current Code:
func generateID(counter int) string {
	return time.Now().Format("20060102150405") + "-" + string(rune(counter))
}

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +39 to +53
func (t *Tracker) LogActivity(userID, action string, metadata map[string]interface{}) *ActivityLog {
t.mu.Lock()
defer t.mu.Unlock()

t.idCounter++
log := ActivityLog{
ID: generateID(t.idCounter),
UserID: userID,
Action: action,
Timestamp: time.Now(),
Metadata: metadata,
}

t.activities[userID] = append(t.activities[userID], log)
return &log

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

The Metadata map reference is stored directly, allowing the caller to mutate it after logging. This can cause unintended data changes and potential data races if the map is modified concurrently elsewhere.

Code Suggestion or Comments
func (t *Tracker) LogActivity(userID, action string, metadata map[string]interface{}) *ActivityLog {
	t.mu.Lock()
	defer t.mu.Unlock()

	// Make a shallow copy of metadata to avoid external mutation
	var metaCopy map[string]interface{}
	if metadata != nil {
		metaCopy = make(map[string]interface{}, len(metadata))
		for k, v := range metadata {
			metaCopy[k] = v
		}
	}

	t.idCounter++
	log := ActivityLog{
		ID:        generateID(t.idCounter),
		UserID:    userID,
		Action:    action,
		Timestamp: time.Now(),
		Metadata:  metaCopy,
	}

	t.activities[userID] = append(t.activities[userID], log)
	return &log
}
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 39-53
Issue Type: robustness-high
Severity: high

Issue Description:
The Metadata map reference is stored directly, allowing the caller to mutate it after logging. This can cause unintended data changes and potential data races if the map is modified concurrently elsewhere.

Current Code:
func (t *Tracker) LogActivity(userID, action string, metadata map[string]interface{}) *ActivityLog {
	t.mu.Lock()
	defer t.mu.Unlock()

	t.idCounter++
	log := ActivityLog{
		ID:        generateID(t.idCounter),
		UserID:    userID,
		Action:    action,
		Timestamp: time.Now(),
		Metadata:  metadata,
	}

	t.activities[userID] = append(t.activities[userID], log)
	return &log
}

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread js-service/package.json
Comment on lines +1 to +5
{
"name": "activity-dashboard-service",
"version": "1.0.0",
"description": "Activity Dashboard TypeScript Service",
"main": "dist/index.js",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Package is missing "private": true, increasing the risk of accidental publication to the public npm registry and potential source/code leakage.

Code Suggestion or Comments
{
  "name": "activity-dashboard-service",
  "version": "1.0.0",
  "private": true,
  "description": "Activity Dashboard TypeScript Service",
  "main": "dist/index.js",
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert json developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/package.json
Lines: 1-5
Issue Type: security-medium
Severity: medium

Issue Description:
Package is missing "private": true, increasing the risk of accidental publication to the public npm registry and potential source/code leakage.

Current Code:
{
  "name": "activity-dashboard-service",
  "version": "1.0.0",
  "description": "Activity Dashboard TypeScript Service",
  "main": "dist/index.js",

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow json best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread js-service/package.json
Comment on lines +13 to +21
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.6",
"@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.17.0",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"typescript": "^5.3.3"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Using caret (^) version ranges in devDependencies can pull in unvetted minor/patch releases during CI runs, increasing supply-chain risk. Pin exact versions and rely on a lockfile to ensure deterministic builds.

Code Suggestion or Comments
"devDependencies": {
    "@jest/globals": "29.7.0",
    "@types/jest": "29.5.11",
    "@types/node": "20.10.6",
    "@typescript-eslint/eslint-plugin": "6.17.0",
    "@typescript-eslint/parser": "6.17.0",
    "eslint": "8.56.0",
    "jest": "29.7.0",
    "ts-jest": "29.1.1",
    "typescript": "5.3.3"
  },
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert json developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/package.json
Lines: 13-21
Issue Type: security-medium
Severity: medium

Issue Description:
Using caret (^) version ranges in devDependencies can pull in unvetted minor/patch releases during CI runs, increasing supply-chain risk. Pin exact versions and rely on a lockfile to ensure deterministic builds.

Current Code:
  "devDependencies": {
    "@jest/globals": "^29.7.0",
    "@types/jest": "^29.5.11",
    "@types/node": "^20.10.6",
    "@typescript-eslint/eslint-plugin": "^6.17.0",
    "@typescript-eslint/parser": "^6.17.0",
    "eslint": "^8.56.0",
    "jest": "^29.7.0",
    "ts-jest": "^29.1.1",
    "typescript": "^5.3.3"
  },

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow json best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +43 to +45
first_ts = self._parse_timestamp(activities[0].get('timestamp'))
last_ts = self._parse_timestamp(activities[-1].get('timestamp'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

get_user_score assumes the input activities are ordered and uses the first and last items directly. If activities are unsorted, this can produce incorrect days_active and actions_per_day calculations.

Code Suggestion or Comments
timestamps = [self._parse_timestamp(act.get('timestamp')) for act in activities]
        timestamps = [t for t in timestamps if t is not None]
        if timestamps:
            timestamps.sort()
            first_ts, last_ts = timestamps[0], timestamps[-1]
            days_active = max((last_ts - first_ts).days, 1)
            actions_per_day = total_actions / days_active
        else:
            actions_per_day = total_actions
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 43-45
Issue Type: functional-medium
Severity: medium

Issue Description:
get_user_score assumes the input activities are ordered and uses the first and last items directly. If activities are unsorted, this can produce incorrect days_active and actions_per_day calculations.

Current Code:
        first_ts = self._parse_timestamp(activities[0].get('timestamp'))
        last_ts = self._parse_timestamp(activities[-1].get('timestamp'))

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +174 to +178
def parse_timestamp(timestamp_str)
Time.parse(timestamp_str)
rescue ArgumentError
Time.now
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

parse_timestamp rescues only ArgumentError. Time.parse can raise TypeError when given nil or non-string input, which would propagate and break timeline generation.

Code Suggestion or Comments
def parse_timestamp(timestamp_str)
    str = timestamp_str.to_s
    return Time.now if str.strip.empty?

    Time.parse(str)
  rescue ArgumentError, TypeError
    Time.now
  end
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 174-178
Issue Type: robustness-medium
Severity: medium

Issue Description:
parse_timestamp rescues only ArgumentError. Time.parse can raise TypeError when given nil or non-string input, which would propagate and break timeline generation.

Current Code:
  def parse_timestamp(timestamp_str)
    Time.parse(timestamp_str)
  rescue ArgumentError
    Time.now
  end

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +62 to +64
first_timestamp: acts.first['timestamp'],
last_timestamp: acts.last['timestamp']
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

first_timestamp and last_timestamp use the original array order within each group, which may not be chronological. This can yield incorrect boundary timestamps.

Code Suggestion or Comments
sorted_acts = acts.sort_by { |a| parse_timestamp(a['timestamp']) }
        first_timestamp: sorted_acts.first && sorted_acts.first['timestamp'],
        last_timestamp: sorted_acts.last && sorted_acts.last['timestamp']
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 62-64
Issue Type: functional-medium
Severity: medium

Issue Description:
first_timestamp and last_timestamp use the original array order within each group, which may not be chronological. This can yield incorrect boundary timestamps.

Current Code:
        first_timestamp: acts.first['timestamp'],
        last_timestamp: acts.last['timestamp']

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
echo "Running Go tests..."
# Test root-level Go files
if ls *.go 1> /dev/null 2>&1; then
go mod init test-repo 2>/dev/null || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Swallowing errors and suppressing output from go mod init can hide real initialization problems and make failures hard to diagnose.

Code Suggestion or Comments
if [ ! -f "go.mod" ]; then
              go mod init test-repo
            fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 29-29
Issue Type: robustness-medium
Severity: medium

Issue Description:
Swallowing errors and suppressing output from go mod init can hide real initialization problems and make failures hard to diagnose.

Current Code:
            go mod init test-repo 2>/dev/null || true

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
Comment on lines +79 to +81
if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
rspec --format documentation *.rb || exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

RSpec is invoked with a wildcard (*.rb), which may run non-test Ruby files. This can cause false positives, unexpected code execution, or failures.

Code Suggestion or Comments
# Test root-level Ruby files
          if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
            rspec --format documentation test*.rb *_spec.rb || exit 1
          fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 79-81
Issue Type: functional-medium
Severity: medium

Issue Description:
RSpec is invoked with a wildcard (*.rb), which may run non-test Ruby files. This can cause false positives, unexpected code execution, or failures.

Current Code:
          # Test root-level Ruby files
          if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
            rspec --format documentation *.rb || exit 1

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
displayName: 'Install Node.js 20'

- script: |
npm install -g ts-node typescript jest @types/jest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Installing global npm packages without pinning versions increases supply-chain risk by pulling the latest potentially compromised versions.

Code Suggestion or Comments
npm install -g ts-node@10.9.1 typescript@5.3.3 jest@29.7.0 @types/jest@29.5.12
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 101-101
Issue Type: security-medium
Severity: medium

Issue Description:
Installing global npm packages without pinning versions increases supply-chain risk by pulling the latest potentially compromised versions.

Current Code:
          npm install -g ts-node typescript jest @types/jest

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

@codity-dev

codity-dev Bot commented Feb 15, 2026

Copy link
Copy Markdown

PR Summary

What Changed

  • Added a cross-language activity tracking/analytics/reporting stack to deliver richer user activity insights and trends.
  • Introduced CI pipelines (GitHub Actions and Azure Pipelines) to run language-specific tests on PRs for faster, consistent feedback.
  • Added TypeScript config and Ruby testing shim to enable incremental development without breaking existing/test scaffolding.

Key Changes by Area

  • Activity Tracking (Go): In-memory tracker supports logging, per-user queries, stats, date-range filtering, and user list/deletion.
  • Analytics & Dashboard (TypeScript): Dashboard service adds date-range filtering, action aggregation/top actions, engagement scoring, session averages, and time grouping.
  • Analysis (Python): ActivityAnalyzer implements pattern detection, scoring, and anomaly detection for behavior insights.
  • Reporting (Ruby): ActivityReporter generates reports, timelines, user comparisons, and JSON export; adds defaults and stubs; rails_helper shim ensures spec compatibility.
  • CI/CD: GitHub Actions workflow runs Java tests; Azure Pipelines “quick tests” run Go/Python/Ruby/JS suites on PRs.

Files Changed

File Changes Summary
.github/workflows/java-tests.yml New GitHub Actions workflow to execute Java tests on PRs.
azure-pipelines.yml Adds “quick tests” pipeline for Go/Python/Ruby/JS test execution on PRs.
go-service/internal/activity/tracker.go Implements in-memory user activity tracker with log/query/stats/date-range and user list/delete.
js-service/tests/.gitkeep Adds placeholder to retain tests directory in VCS.
js-service/package.json Declares dashboard service package and scripts for build/test.
js-service/src/activity-dashboard.ts New dashboard service for summaries: filtering, aggregation/top actions, engagement score, sessions, time grouping.
js-service/tsconfig.json Introduces TypeScript configuration for the JS service.
python-service/src/activity_analyzer.py Adds ActivityAnalyzer with pattern detection, scoring, and anomaly detection.
ruby-service/app/activity_reporter.rb Adds ActivityReporter for reports/timelines/comparisons and JSON export with defaults/stubs.
ruby-service/spec/rails_helper.rb Provides shim for Rails-like spec compatibility.

Potential Impact

  • In-memory tracker is non-durable and may grow memory usage with high activity volume.
  • Cross-language time zone/date-range handling may produce inconsistent aggregates if not normalized.
  • CI additions may increase PR runtime; no significant breaking changes.

Review Focus Areas

  • Time normalization and date-range grouping across Go/TS/Python/Ruby components.
  • Memory lifecycle and deletion semantics in go-service/internal/activity/tracker.go.
  • Scoring/aggregation thresholds and anomaly detection logic stability in analytics components.

Architecture

  • Design Decisions: Selected an in-memory Go tracker for simplicity and speed during early development; split analytics/reporting by language to leverage existing service boundaries; adopted dual CI (GHA + Azure) to align with team/tooling constraints and ensure broad coverage.
  • Scalability & Extensibility: In-memory storage is not horizontally scalable or durable; persistence/sharding are out of scope for this iteration but the layered design allows future replacement of the storage/analysis layers.
  • Risks: Intentional tradeoff—lack of persistence and potential memory growth; unintentional risks—time zone/schema drift across services and increased maintenance from multi-language surface area.

@codity-dev

codity-dev Bot commented Feb 15, 2026

Copy link
Copy Markdown

Workflow Diagrams

Automatically generated sequence diagrams showing the workflows in this PR

1. Service Integration Flow

Medium complexity • Components: java-tests.yml, azure-pipelines.yml, activity tracker in go-service

sequenceDiagram
    title PR: Integration of Java Tests and Activity Tracking Functionality

    participant Client
    participant GitHubActions as GitHub Actions
    participant AzurePipelines as Azure Pipelines
    participant GoService as Go Service
    participant PythonService as Python Service
    participant RubyService as Ruby Service
    participant JavaService as Java Service
    participant JSService as JavaScript Service

    Client->>GitHubActions: Trigger PR
    GitHubActions->>JavaService: Run Java Tests
    JavaService->>GitHubActions: Return test results

    GitHubActions->>AzurePipelines: Trigger CI for Go, Python, Ruby, JS
    AzurePipelines->>GoService: Run Go Tests
    GoService->>AzurePipelines: Return Go test results

    AzurePipelines->>PythonService: Run Python Tests
    PythonService->>AzurePipelines: Return Python test results

    AzurePipelines->>RubyService: Run Ruby Tests
    RubyService->>AzurePipelines: Return Ruby test results

    AzurePipelines->>JSService: Run JavaScript Tests
    JSService->>AzurePipelines: Return JS test results

    Client->>GoService: POST /analyze (content)
    GoService->>PythonService: Call /review (content)
    PythonService->>GoService: Return review results
    GoService->>Client: Return analysis results

    Client->>GoService: POST /metrics (content)
    GoService->>PythonService: Call /review (content)
    PythonService->>GoService: Return review results
    GoService->>Client: Return metrics results

    note right of GoService: New activity tracking functionality\nintegrated with analysis and metrics
    note right of JSService: New activity dashboard functionality\nfor visualizing results
Loading

Note: Diagrams show detected patterns only. Complex workflows may require manual review.

Comment on lines +16 to +22
uses: actions/checkout@v4

- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Reusable actions are referenced by a mutable version tag (v4). This allows supply-chain attacks if the tag is moved. Pin actions to an immutable commit SHA.

Code Suggestion or Comments
- name: Checkout code
      uses: actions/checkout@<commit-sha-for-v4>
      # NOTE: Replace <commit-sha-for-v4> with the full commit SHA for the desired v4 release

    - name: Set up Java
      uses: actions/setup-java@<commit-sha-for-v4>
      # NOTE: Replace <commit-sha-for-v4> with the full commit SHA for the desired v4 release
      with:
        distribution: 'temurin'
        java-version: '17'
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 16-22
Issue Type: security-high
Severity: high

Issue Description:
Reusable actions are referenced by a mutable version tag (v4). This allows supply-chain attacks if the tag is moved. Pin actions to an immutable commit SHA.

Current Code:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up Java
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +24 to +42
- name: Run tests with Maven or Gradle
run: |
# Check for Maven
if [ -f "pom.xml" ]; then
echo "Found Maven project"
mvn test -B
# Check for Gradle
elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
echo "Found Gradle project"
if [ -f "gradlew" ]; then
chmod +x gradlew
./gradlew test
else
gradle test
fi
else
echo "No Maven or Gradle build file found"
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Gradle Wrapper is executed without prior integrity verification. A compromised gradle-wrapper.jar in a PR could execute arbitrary code on the runner. Validate the wrapper before running it.

Code Suggestion or Comments
- name: Validate Gradle Wrapper
      uses: gradle/wrapper-validation-action@<commit-sha>
      # NOTE: Replace <commit-sha> with the full commit SHA for the desired release

    - name: Run tests with Maven or Gradle
      run: |
        # Check for Maven
        if [ -f "pom.xml" ]; then
          echo "Found Maven project"
          mvn test -B
        # Check for Gradle
        elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
          echo "Found Gradle project"
          if [ -f "gradlew" ]; then
            chmod +x gradlew
            ./gradlew test
          else
            gradle test
          fi
        else
          echo "No Maven or Gradle build file found"
          exit 1
        fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 24-42
Issue Type: security-high
Severity: high

Issue Description:
Gradle Wrapper is executed without prior integrity verification. A compromised gradle-wrapper.jar in a PR could execute arbitrary code on the runner. Validate the wrapper before running it.

Current Code:
    - name: Run tests with Maven or Gradle
      run: |
        # Check for Maven
        if [ -f "pom.xml" ]; then
          echo "Found Maven project"
          mvn test -B
        # Check for Gradle
        elif [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
          echo "Found Gradle project"
          if [ -f "gradlew" ]; then
            chmod +x gradlew
            ./gradlew test
          else
            gradle test
          fi
        else
          echo "No Maven or Gradle build file found"
          exit 1
        fi

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +155 to +157
func generateID(counter int) string {
return time.Now().Format("20060102150405") + "-" + string(rune(counter))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

generateID converts the counter with string(rune(counter)), which produces a single Unicode character (e.g., counter=1 -> "\x01") instead of the decimal digits. This yields non-printable/unexpected characters in IDs and risks collisions/invalid IDs.

Code Suggestion or Comments
func generateID(counter int) string {
	// Note: requires importing "strconv"
	return time.Now().Format("20060102150405") + "-" + strconv.Itoa(counter)
}
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 155-157
Issue Type: functional-high
Severity: high

Issue Description:
generateID converts the counter with string(rune(counter)), which produces a single Unicode character (e.g., counter=1 -> "\x01") instead of the decimal digits. This yields non-printable/unexpected characters in IDs and risks collisions/invalid IDs.

Current Code:
func generateID(counter int) string {
	return time.Now().Format("20060102150405") + "-" + string(rune(counter))
}

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +49 to +50
Metadata: metadata,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Metadata map is stored by reference, allowing external mutation after LogActivity returns. This can lead to data races or unintended changes to stored logs if the caller modifies the original map.

Code Suggestion or Comments
// Safely copy metadata to avoid external mutations
		Metadata: func() map[string]interface{} {
			if metadata == nil {
				return nil
			}
			m := make(map[string]interface{}, len(metadata))
			for k, v := range metadata {
				m[k] = v
			}
			return m
		}(),
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 49-50
Issue Type: robustness-high
Severity: high

Issue Description:
Metadata map is stored by reference, allowing external mutation after LogActivity returns. This can lead to data races or unintended changes to stored logs if the caller modifies the original map.

Current Code:
		Metadata:  metadata,

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
Comment on lines +79 to +81
if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
rspec --format documentation *.rb || exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

The test discovery logic checks for test files but then runs RSpec against all Ruby files (*.rb), which can execute non-test code and cause false failures.

Code Suggestion or Comments
if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
            rspec --format documentation test*.rb *_spec.rb || exit 1
          fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 79-81
Issue Type: functional-high
Severity: high

Issue Description:
The test discovery logic checks for test files but then runs RSpec against all Ruby files (*.rb), which can execute non-test code and cause false failures.

Current Code:
          if ls test*.rb *_spec.rb 1> /dev/null 2>&1; then
            rspec --format documentation *.rb || exit 1
          fi

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
Comment on lines +101 to +103
npm install -g ts-node typescript jest @types/jest
echo "Running JavaScript/TypeScript tests..."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Installing packages globally with npm without version pinning introduces significant supply-chain risk and non-reproducible builds. Relying on global jest for npm test is brittle.

Code Suggestion or Comments
echo "Running JavaScript/TypeScript tests..."

          # Use local, pinned devDependencies instead of global installs
          if [ ! -f "package.json" ]; then
            cat > package.json <<'EOF'
{
  "private": true,
  "devDependencies": {
    "jest": "29.7.0",
    "typescript": "5.3.3",
    "ts-node": "10.9.2",
    "@types/jest": "29.5.12"
  },
  "scripts": { "test": "jest" }
}
EOF
          fi
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 101-103
Issue Type: security-high
Severity: high

Issue Description:
Installing packages globally with npm without version pinning introduces significant supply-chain risk and non-reproducible builds. Relying on global jest for `npm test` is brittle.

Current Code:
          npm install -g ts-node typescript jest @types/jest
          echo "Running JavaScript/TypeScript tests..."

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread js-service/package.json
Comment on lines +1 to +5
{
"name": "activity-dashboard-service",
"version": "1.0.0",
"description": "Activity Dashboard TypeScript Service",
"main": "dist/index.js",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Top-level package.json is missing "private": true, which increases the risk of accidentally publishing the internal service to the public npm registry, potentially exposing proprietary code or internal configurations.

Code Suggestion or Comments
{
  "name": "activity-dashboard-service",
  "private": true,
  "version": "1.0.0",
  "description": "Activity Dashboard TypeScript Service",
  "main": "dist/index.js",
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert json developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/package.json
Lines: 1-5
Issue Type: security-medium
Severity: medium

Issue Description:
Top-level package.json is missing "private": true, which increases the risk of accidentally publishing the internal service to the public npm registry, potentially exposing proprietary code or internal configurations.

Current Code:
{
  "name": "activity-dashboard-service",
  "version": "1.0.0",
  "description": "Activity Dashboard TypeScript Service",
  "main": "dist/index.js",

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow json best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread js-service/package.json
Comment on lines +12 to +22
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.11",
"@types/node": "^20.10.6",
"@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.17.0",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"typescript": "^5.3.3"
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Dev dependency versions are specified with caret (^) ranges, which permits unpinned minor/patch updates. This can lead to non-reproducible builds and supply-chain risk if an upstream dependency is compromised. Pin exact versions and rely on a lockfile for deterministic installs.

Code Suggestion or Comments
"devDependencies": {
    "@jest/globals": "29.7.0",
    "@types/jest": "29.5.11",
    "@types/node": "20.10.6",
    "@typescript-eslint/eslint-plugin": "6.17.0",
    "@typescript-eslint/parser": "6.17.0",
    "eslint": "8.56.0",
    "jest": "29.7.0",
    "ts-jest": "29.1.1",
    "typescript": "5.3.3"
  },
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert json developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/package.json
Lines: 12-22
Issue Type: security-medium
Severity: medium

Issue Description:
Dev dependency versions are specified with caret (^) ranges, which permits unpinned minor/patch updates. This can lead to non-reproducible builds and supply-chain risk if an upstream dependency is compromised. Pin exact versions and rely on a lockfile for deterministic installs.

Current Code:
  "devDependencies": {
    "@jest/globals": "^29.7.0",
    "@types/jest": "^29.5.11",
    "@types/node": "^20.10.6",
    "@typescript-eslint/eslint-plugin": "^6.17.0",
    "@typescript-eslint/parser": "^6.17.0",
    "eslint": "^8.56.0",
    "jest": "^29.7.0",
    "ts-jest": "^29.1.1",
    "typescript": "^5.3.3"
  },

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow json best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

return parseFloat((activities.length / sessions).toFixed(2));
}

private groupByPeriod(activities: Activity[], periodType: string): Record<string, Activity[]> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainability

The parameter 'periodType' is typed as 'string' here, while other methods (e.g., getActivityTrends) use a stricter union type. Using a broad 'string' defeats compile-time checks and allows invalid values.

Code Suggestion or Comments
private groupByPeriod(
        activities: Activity[],
        periodType: 'hour' | 'day' | 'week' | 'month'
    ): Record<string, Activity[]> {
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert typescript developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/src/activity-dashboard.ts
Lines: 200-200
Issue Type: maintainability-medium
Severity: medium

Issue Description:
The parameter 'periodType' is typed as 'string' here, while other methods (e.g., getActivityTrends) use a stricter union type. Using a broad 'string' defeats compile-time checks and allows invalid values.

Current Code:
    private groupByPeriod(activities: Activity[], periodType: string): Record<string, Activity[]> {

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow typescript best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

return grouped;
}

private getPeriodKey(date: Date, periodType: string): string {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainability

The parameter 'periodType' should use the same discriminated union type as callers to ensure only valid period values are passed.

Code Suggestion or Comments
private getPeriodKey(date: Date, periodType: 'hour' | 'day' | 'week' | 'month'): string {
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert typescript developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/src/activity-dashboard.ts
Lines: 216-216
Issue Type: maintainability-medium
Severity: medium

Issue Description:
The parameter 'periodType' should use the same discriminated union type as callers to ensure only valid period values are passed.

Current Code:
    private getPeriodKey(date: Date, periodType: string): string {

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow typescript best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +34 to +36
constructor(activities: Activity[] = []) {
this.activities = activities;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

The code assumes 'timestamp' is always a Date object. When activities are created from JSON or external sources, timestamps may be strings, causing runtime errors when calling getTime(). Normalize inputs.

Code Suggestion or Comments
constructor(activities: Activity[] = []) {
        this.activities = activities.map(a => ({
            ...a,
            timestamp: a.timestamp instanceof Date ? a.timestamp : new Date(a.timestamp as unknown as string)
        }));
    }
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert typescript developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/src/activity-dashboard.ts
Lines: 34-36
Issue Type: robustness-medium
Severity: medium

Issue Description:
The code assumes 'timestamp' is always a Date object. When activities are created from JSON or external sources, timestamps may be strings, causing runtime errors when calling getTime(). Normalize inputs.

Current Code:
    constructor(activities: Activity[] = []) {
        this.activities = activities;
    }

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow typescript best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +10 to +13
jobs:
test:
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

The workflow does not explicitly restrict GITHUB_TOKEN permissions. Explicitly setting least-privilege permissions reduces blast radius if compromised.

Code Suggestion or Comments
permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: .github/workflows/java-tests.yml
Lines: 10-13
Issue Type: security-medium
Severity: medium

Issue Description:
The workflow does not explicitly restrict GITHUB_TOKEN permissions. Explicitly setting least-privilege permissions reduces blast radius if compromised.

Current Code:
jobs:
  test:
    runs-on: ubuntu-latest

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +65 to +67
result := make([]ActivityLog, len(logs))
copy(result, logs)
return result

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Returning a shallow copy of ActivityLog structs still shares the underlying Metadata maps. Callers can mutate Metadata and affect internal state, potentially causing data races or unexpected behavior.

Code Suggestion or Comments
result := make([]ActivityLog, len(logs))
	for i, l := range logs {
		result[i] = l
		if l.Metadata != nil {
			m := make(map[string]interface{}, len(l.Metadata))
			for k, v := range l.Metadata {
				m[k] = v
			}
			result[i].Metadata = m
		}
	}
	return result
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 65-67
Issue Type: robustness-medium
Severity: medium

Issue Description:
Returning a shallow copy of ActivityLog structs still shares the underlying Metadata maps. Callers can mutate Metadata and affect internal state, potentially causing data races or unexpected behavior.

Current Code:
	result := make([]ActivityLog, len(logs))
	copy(result, logs)
	return result

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +119 to +125
var filtered []ActivityLog
for _, log := range logs {
if (log.Timestamp.Equal(start) || log.Timestamp.After(start)) &&
(log.Timestamp.Equal(end) || log.Timestamp.Before(end)) {
filtered = append(filtered, log)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Filtered results are appended as shallow copies, so Metadata maps remain shared with internal state. External mutation of returned Metadata can affect stored logs.

Code Suggestion or Comments
var filtered []ActivityLog
	for _, l := range logs {
		if (l.Timestamp.Equal(start) || l.Timestamp.After(start)) &&
			(l.Timestamp.Equal(end) || l.Timestamp.Before(end)) {
			nl := l
			if l.Metadata != nil {
				m := make(map[string]interface{}, len(l.Metadata))
				for k, v := range l.Metadata {
					m[k] = v
				}
				nl.Metadata = m
			}
			filtered = append(filtered, nl)
		}
	}
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert go developer with deep knowledge of security, performance, and best practices.

### Context

File: go-service/internal/activity/tracker.go
Lines: 119-125
Issue Type: robustness-medium
Severity: medium

Issue Description:
Filtered results are appended as shallow copies, so Metadata maps remain shared with internal state. External mutation of returned Metadata can affect stored logs.

Current Code:
	var filtered []ActivityLog
	for _, log := range logs {
		if (log.Timestamp.Equal(start) || log.Timestamp.After(start)) &&
			(log.Timestamp.Equal(end) || log.Timestamp.Before(end)) {
			filtered = append(filtered, log)
		}
	}

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow go best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +43 to +51
first_ts = self._parse_timestamp(activities[0].get('timestamp'))
last_ts = self._parse_timestamp(activities[-1].get('timestamp'))

if first_ts and last_ts:
days_active = max((last_ts - first_ts).days, 1)
actions_per_day = total_actions / days_active
else:
actions_per_day = total_actions

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

User score relies on activities[0] and activities[-1] without ensuring chronological order. If activities are unsorted or contain unparseable timestamps at the ends, days_active and actions_per_day can be inaccurate.

Code Suggestion or Comments
# Use all valid timestamps to avoid relying on input order
        timestamps = [self._parse_timestamp(a.get('timestamp')) for a in activities]
        timestamps = [ts for ts in timestamps if ts is not None]

        if len(timestamps) >= 2:
            first_ts = min(timestamps)
            last_ts = max(timestamps)
            days_active = max((last_ts - first_ts).days, 1)
            actions_per_day = total_actions / days_active
        else:
            actions_per_day = total_actions
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 43-51
Issue Type: functional-medium
Severity: medium

Issue Description:
User score relies on activities[0] and activities[-1] without ensuring chronological order. If activities are unsorted or contain unparseable timestamps at the ends, days_active and actions_per_day can be inaccurate.

Current Code:
        first_ts = self._parse_timestamp(activities[0].get('timestamp'))
        last_ts = self._parse_timestamp(activities[-1].get('timestamp'))

        if first_ts and last_ts:
            days_active = max((last_ts - first_ts).days, 1)
            actions_per_day = total_actions / days_active
        else:
            actions_per_day = total_actions

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +186 to +196
def _parse_timestamp(self, ts: Any) -> Optional[datetime]:
if isinstance(ts, datetime):
return ts

if isinstance(ts, str):
try:
return datetime.fromisoformat(ts.replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass

return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Datetime handling can mix naive and timezone-aware timestamps, leading to TypeError during subtraction in interval and range calculations. Normalize timestamps in _parse_timestamp to a consistent timezone (e.g., UTC). Also add from datetime import timezone at the top of the file.

Code Suggestion or Comments
def _parse_timestamp(self, ts: Any) -> Optional[datetime]:
        if isinstance(ts, datetime):
            # Normalize to timezone-aware (assume UTC if naive)
            return ts if ts.tzinfo is not None else ts.replace(tzinfo=timezone.utc)

        if isinstance(ts, str):
            try:
                dt = datetime.fromisoformat(ts.replace('Z', '+00:00'))
                return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
            except (ValueError, AttributeError):
                pass

        return None
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 186-196
Issue Type: robustness-medium
Severity: medium

Issue Description:
Datetime handling can mix naive and timezone-aware timestamps, leading to TypeError during subtraction in interval and range calculations. Normalize timestamps in _parse_timestamp to a consistent timezone (e.g., UTC). Also add `from datetime import timezone` at the top of the file.

Current Code:
    def _parse_timestamp(self, ts: Any) -> Optional[datetime]:
        if isinstance(ts, datetime):
            return ts

        if isinstance(ts, str):
            try:
                return datetime.fromisoformat(ts.replace('Z', '+00:00'))
            except (ValueError, AttributeError):
                pass

        return None

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +68 to +79
def export_to_json(report, filepath = nil)
json_data = JSON.pretty_generate(report)

if filepath
File.write(filepath, json_data)
{ success: true, filepath: filepath, size: json_data.bytesize }
else
{ success: true, data: json_data }
end
rescue StandardError => e
{ success: false, error: e.message }
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

export_to_json writes to an arbitrary, unvalidated filepath. If filepath is user-controlled, this enables path traversal and arbitrary file write anywhere the process has permission. It also returns raw exception messages, which can leak filesystem details.

Code Suggestion or Comments
def export_to_json(report, filepath = nil)
    json_data = JSON.pretty_generate(report)

    if filepath
      safe_base = ENV.fetch('REPORTS_DIR', Dir.pwd)
      base_dir = File.expand_path(safe_base)
      target_path = File.expand_path(filepath, base_dir)

      unless target_path.start_with?(base_dir + File::SEPARATOR)
        return { success: false, error: 'Invalid file path' }
      end

      File.open(target_path, 'w', 0o600) { |f| f.write(json_data) }
      { success: true, filepath: target_path, size: json_data.bytesize }
    else
      { success: true, data: json_data }
    end
  rescue StandardError
    { success: false, error: 'Failed to export report' }
  end
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 68-79
Issue Type: security-medium
Severity: medium

Issue Description:
export_to_json writes to an arbitrary, unvalidated filepath. If filepath is user-controlled, this enables path traversal and arbitrary file write anywhere the process has permission. It also returns raw exception messages, which can leak filesystem details.

Current Code:
  def export_to_json(report, filepath = nil)
    json_data = JSON.pretty_generate(report)

    if filepath
      File.write(filepath, json_data)
      { success: true, filepath: filepath, size: json_data.bytesize }
    else
      { success: true, data: json_data }
    end
  rescue StandardError => e
    { success: false, error: e.message }
  end

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +56 to +64
grouped.map do |period, acts|
action_counts = acts.group_by { |a| a['action'] }.transform_values(&:count)
{
period: period,
total_actions: acts.count,
actions: action_counts,
first_timestamp: acts.first['timestamp'],
last_timestamp: acts.last['timestamp']
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality

Within format_timeline, first_timestamp and last_timestamp rely on the array's current order. Since acts is not sorted, these may not represent the actual earliest and latest timestamps in the period.

Code Suggestion or Comments
grouped.map do |period, acts|
      action_counts = acts.group_by { |a| a['action'] }.transform_values(&:count)
      sorted_acts = acts.sort_by { |a| parse_timestamp(a['timestamp']) }
      {
        period: period,
        total_actions: acts.count,
        actions: action_counts,
        first_timestamp: sorted_acts.first['timestamp'],
        last_timestamp: sorted_acts.last['timestamp']
      }
    end.sort_by { |entry| entry[:period] }
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 56-64
Issue Type: functional-medium
Severity: medium

Issue Description:
Within format_timeline, first_timestamp and last_timestamp rely on the array's current order. Since acts is not sorted, these may not represent the actual earliest and latest timestamps in the period.

Current Code:
    grouped.map do |period, acts|
      action_counts = acts.group_by { |a| a['action'] }.transform_values(&:count)
      {
        period: period,
        total_actions: acts.count,
        actions: action_counts,
        first_timestamp: acts.first['timestamp'],
        last_timestamp: acts.last['timestamp']
      }
    end.sort_by { |entry| entry[:period] }

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment on lines +174 to +177
def parse_timestamp(timestamp_str)
Time.parse(timestamp_str)
rescue ArgumentError
Time.now

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

parse_timestamp rescues only ArgumentError. Time.parse can also raise TypeError (e.g., when timestamp_str is nil or non-string), which will bubble up and break timeline generation.

Code Suggestion or Comments
def parse_timestamp(timestamp_str)
    return Time.now if timestamp_str.nil? || timestamp_str.to_s.strip.empty?

    Time.parse(timestamp_str)
  rescue ArgumentError, TypeError
    Time.now
  end
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert ruby developer with deep knowledge of security, performance, and best practices.

### Context

File: ruby-service/app/activity_reporter.rb
Lines: 174-177
Issue Type: robustness-medium
Severity: medium

Issue Description:
parse_timestamp rescues only ArgumentError. Time.parse can also raise TypeError (e.g., when timestamp_str is nil or non-string), which will bubble up and break timeline generation.

Current Code:
  def parse_timestamp(timestamp_str)
    Time.parse(timestamp_str)
  rescue ArgumentError
    Time.now
  end

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow ruby best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
displayName: 'Use Python 3.11'

- script: |
pip install pytest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Unpinned dependency installation in CI can lead to supply-chain compromise and non-reproducible builds as the latest version of pytest is fetched each run.

Code Suggestion or Comments
pip install pytest==7.4.4 --disable-pip-version-check --no-input
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 51-51
Issue Type: security-medium
Severity: medium

Issue Description:
Unpinned dependency installation in CI can lead to supply-chain compromise and non-reproducible builds as the latest version of pytest is fetched each run.

Current Code:
          pip install pytest

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
# Test python-service
if [ -d "python-service" ]; then
cd python-service
pip install -r requirements.txt 2>/dev/null || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robustness

Swallowing dependency installation errors (redirecting to /dev/null and forcing success) can cause tests to run with missing dependencies, leading to flaky or misleading failures.

Code Suggestion or Comments
pip install -r requirements.txt || { echo "Failed to install python-service requirements"; exit 1; }
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 61-61
Issue Type: robustness-medium
Severity: medium

Issue Description:
Swallowing dependency installation errors (redirecting to /dev/null and forcing success) can cause tests to run with missing dependencies, leading to flaky or misleading failures.

Current Code:
            pip install -r requirements.txt 2>/dev/null || true

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
displayName: 'Use Ruby 3.2'

- script: |
gem install rspec

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security

Unpinned global gem installation increases supply-chain risk and reduces reproducibility. The latest RSpec version is fetched at runtime.

Code Suggestion or Comments
gem install rspec -v 3.12.0 --no-document
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 76-76
Issue Type: security-medium
Severity: medium

Issue Description:
Unpinned global gem installation increases supply-chain risk and reduces reproducibility. The latest RSpec version is fetched at runtime.

Current Code:
          gem install rspec

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

Comment thread azure-pipelines.yml
# Test js-service
if [ -d "js-service" ]; then
cd js-service
npm install

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainability

Using npm install in CI does not enforce the lockfile and can yield non-reproducible dependency trees. npm ci is recommended for CI environments.

Code Suggestion or Comments
npm ci
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert yaml developer with deep knowledge of security, performance, and best practices.

### Context

File: azure-pipelines.yml
Lines: 116-116
Issue Type: maintainability-medium
Severity: medium

Issue Description:
Using `npm install` in CI does not enforce the lockfile and can yield non-reproducible dependency trees. `npm ci` is recommended for CI environments.

Current Code:
            npm install

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow yaml best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---


Like Dislike

@codity-dev

codity-dev Bot commented Feb 15, 2026

Copy link
Copy Markdown

Nitpicks (Low Priority)

Found 2 low-priority suggestions for code improvement

Click to expand nitpicks

js-service/src/activity-dashboard.ts (line 6)

Maintainability

The use of the 'any' type in TypeScript weakens type safety and can hide runtime issues. Prefer 'unknown' or a well-defined metadata interface to maintain stronger typing.

Code Suggestion or Comments
metadata?: Record<string, unknown>;
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert typescript developer with deep knowledge of security, performance, and best practices.

### Context

File: js-service/src/activity-dashboard.ts
Lines: 6-6
Issue Type: maintainability-low
Severity: low

Issue Description:
The use of the 'any' type in TypeScript weakens type safety and can hide runtime issues. Prefer 'unknown' or a well-defined metadata interface to maintain stronger typing.

Current Code:
    metadata?: Record<string, any>;

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow typescript best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



python-service/src/activity_analyzer.py (lines 136-140)

Functionality

Action sequence detection depends on the incoming order of activities. If the input is not chronological, identified sequences may be misleading. Sorting by timestamp makes results deterministic and time-correct.

Code Suggestion or Comments
sequences = []
        # Build chronological sequences based on parsed timestamps
        acts_with_ts = [
            (self._parse_timestamp(a.get('timestamp')), a.get('action', ''))
            for a in activities
        ]
        acts_with_ts = [(ts, action) for ts, action in acts_with_ts if ts is not None]
        acts_with_ts.sort(key=lambda x: x[0])

        for i in range(len(acts_with_ts) - 2):
            seq = tuple(acts_with_ts[j][1] for j in range(i, i + 3))
            sequences.append(seq)
Prompt for AI assistance

Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:

You are an expert python developer with deep knowledge of security, performance, and best practices.

### Context

File: python-service/src/activity_analyzer.py
Lines: 136-140
Issue Type: functional-low
Severity: low

Issue Description:
Action sequence detection depends on the incoming order of activities. If the input is not chronological, identified sequences may be misleading. Sorting by timestamp makes results deterministic and time-correct.

Current Code:
        sequences = []
        for i in range(len(activities) - 2):
            seq = tuple(act.get('action', '') for act in activities[i:i+3])
            sequences.append(seq)

---

### Instructions

1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow python best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed

### Constraints

- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready

---



Like Dislike

@codity-dev

codity-dev Bot commented Feb 15, 2026

Copy link
Copy Markdown

PR review is completed!

@codity-dev

codity-dev Bot commented Feb 15, 2026

Copy link
Copy Markdown

🔐 Security Scan

🔍 Security scan in progress...

Analyzing code for:

  • 🔑 Hardcoded secrets and credentials
  • 💉 Injection vulnerabilities (SQL, Command, XSS)
  • 🔐 Authentication and authorization issues
  • 🔒 Cryptographic weaknesses

Results will be posted shortly...

1 similar comment
@codity-dev

codity-dev Bot commented Feb 21, 2026

Copy link
Copy Markdown

🔐 Security Scan

🔍 Security scan in progress...

Analyzing code for:

  • 🔑 Hardcoded secrets and credentials
  • 💉 Injection vulnerabilities (SQL, Command, XSS)
  • 🔐 Authentication and authorization issues
  • 🔒 Cryptographic weaknesses

Results will be posted shortly...

@codity-dev

codity-dev Bot commented Feb 21, 2026

Copy link
Copy Markdown

🔐 Security Scan Summary

Metric Value
Vulnerabilities Critical: 0
Overall Risk 🟡 Medium
Files Scanned 10

Consider addressing security findings before merging

Scan completed in 318.6s

📋 Top 20 Critical Vulnerabilities (40 total found)

1. SEC-004 (CWE-829) 🟠 HIGH

📁 .github/workflows/java-tests.yml (line 35)
🏷️ Category: Other

./gradlew test

Executing repository-provided Gradle wrapper './gradlew test' can run arbitrary code contained in the wrapper or build scripts on PRs.

💡 Fix: Validate gradlew checksum or disallow executing repo-provided wrappers for untrusted PRs. Run in a sandbox and ensure no secrets are exposed.


2. SEC-019 (CWE-22) 🟠 HIGH

📁 ruby-service/app/activity_reporter.rb (line 72)
🏷️ Category: Injection

File.write(filepath, json_data)

Unvalidated file path used in File.write allows path traversal and arbitrary file overwrite if user controls 'filepath'.

💡 Fix: Validate and sanitize 'filepath'. Restrict writes to a specific directory, use File.expand_path and check it stays within an allowed base path. Consider generating filenames server-side.


3. SEC-001 (CWE-829) 🟡 MEDIUM

📁 .github/workflows/java-tests.yml (line 16)
🏷️ Category: Other

uses: actions/checkout@v4

Mutable action version (pin to SHA)

💡 Fix: Review the security issue and implement appropriate mitigations.


4. SEC-001 (CWE-494) 🟡 MEDIUM

📁 .github/workflows/java-tests.yml (line 16)
🏷️ Category: SAST

uses: actions/checkout@v4

GitHub Action uses unpinned action version 'actions/checkout@v4'. Not pinning to a commit SHA can allow supply-chain attacks if the action tag is compromised.

💡 Fix: Pin the action to a specific commit SHA, e.g., 'uses: actions/checkout@' and enable Dependabot to update it regularly.


5. SEC-003 (CWE-829) 🟡 MEDIUM

📁 .github/workflows/java-tests.yml (line 29)
🏷️ Category: Other

mvn test -B

Workflow executes 'mvn test' on pull requests. Tests/build scripts from untrusted forks can run arbitrary code in CI environment (supply-chain risk).

💡 Fix: Restrict PR workflows to run in isolated environment without secrets; require approval for first-time contributors; or use a sandbox container/VM for running untrusted builds/tests.


6. SEC-006 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 29)
🏷️ Category: Other

go test -v . || exit 1

Azure Pipeline runs 'go test -v .' on untrusted PR code. Go tests can execute arbitrary code during test execution.

💡 Fix: Run tests in a locked-down sandbox with no secrets or limit PR triggers; require manual approval or use a separate, restricted pipeline for untrusted contributions.


7. SEC-007 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 36)
🏷️ Category: Other

go test -v ./... || exit 1

Pipeline runs 'go test -v ./...' which can execute arbitrary test code across the module on PRs.

💡 Fix: Isolate execution environment and ensure no secrets are available to PR jobs. Consider approval gates for external contributors.


8. SEC-008 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 54)
🏷️ Category: Other

pytest -v test_*.py || exit 1

Pipeline executes 'pytest -v test_*.py' on PRs. Pytest collection/fixtures can run arbitrary code.

💡 Fix: Run in sandboxed environment for untrusted PRs and avoid exposing secrets to PR jobs.


9. SEC-010 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 79)
🏷️ Category: Other

rspec --format documentation *.rb || exit 1

Pipeline runs 'rspec' on PRs. Specs can execute arbitrary code during runtime.

💡 Fix: Isolate and sandbox CI environment for PRs; require approvals for external contributions before running tests.


10. SEC-011 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 86)
🏷️ Category: Other

bundle exec rspec --format documentation || exit 1

Pipeline executes 'bundle exec rspec' which can run arbitrary code in Gemfile and spec files on PRs.

💡 Fix: Run in hardened sandbox; avoid exposing secrets to PR jobs; require approvals.


11. SEC-012 (CWE-829) 🟡 MEDIUM

📁 azure-pipelines.yml (line 109)
🏷️ Category: Other

npm test || exit 1

Pipeline runs 'npm test' on PRs. npm test scripts can execute arbitrary commands defined in package.json provided by the PR.

💡 Fix: Use isolated containers and disable access to sensitive environment variables; require approvals for running CI on untrusted contributions.


12. SEC-014 (CWE-494) 🟡 MEDIUM

📁 azure-pipelines.yml (line 50)
🏷️ Category: SAST

pip install pytest

Installing unpinned Python package 'pytest' without version pinning is a supply-chain risk.

💡 Fix: Pin exact versions (e.g., 'pip install pytest==') and verify integrity (hash checking).


13. SEC-015 (CWE-494) 🟡 MEDIUM

📁 azure-pipelines.yml (line 75)
🏷️ Category: SAST

gem install rspec

Installing unpinned Ruby gem 'rspec' without version pinning introduces supply-chain risk.

💡 Fix: Pin gem versions or use Gemfile.lock and 'bundle install --frozen' to ensure deterministic dependencies.


14. SEC-016 (CWE-494) 🟡 MEDIUM

📁 azure-pipelines.yml (line 115)
🏷️ Category: SAST

npm install

Running 'npm install' without lockfile enforcement or integrity checks can lead to dependency confusion or malicious dependency execution.

💡 Fix: Commit and enforce package-lock.json and run 'npm ci' instead of 'npm install'. Consider 'npm ci --ignore-scripts' when feasible.


15. SEC-017 (CWE-494) 🟡 MEDIUM

📁 azure-pipelines.yml (line 100)
🏷️ Category: SAST

npm install -g ts-node typescript jest @types/jest

Installing global npm packages without version pinning increases supply-chain risk.

💡 Fix: Pin exact versions and consider avoiding global installs in CI. Use 'npm ci' with a lockfile for deterministic installs.


16. SEC-020 (CWE-209) 🟡 MEDIUM

📁 ruby-service/app/activity_reporter.rb (line 78)
🏷️ Category: Other

{ success: false, error: e.message }

Error handling returns raw exception message to the caller, potentially leaking sensitive internal information.

💡 Fix: Log detailed errors server-side and return a generic error message to clients. Avoid exposing exception messages directly.


17. SEC-021 (CWE-918) 🟡 MEDIUM

📁 ruby-service/app/activity_reporter.rb (line 5)
🏷️ Category: Injection

def initialize(go_service_url: 'http://localhost:8080', python_service_url: 'http://localhost:8081')

Configurable service URL 'go_service_url' can be user-controlled and used for HTTP calls, enabling potential SSRF.

💡 Fix: Validate URLs against an allowlist, restrict to expected hostnames/IP ranges, and disallow localhost/metadata endpoints. Use URI parsing and network-level egress controls.


18. SEC-023 (CWE-319) 🟡 MEDIUM

📁 ruby-service/app/activity_reporter.rb (line 5)
🏷️ Category: Crypto

go_service_url: 'http://localhost:8080', python_service_url: 'http://localhost:8081'

Service URLs use cleartext HTTP by default. Transmitting data over HTTP can expose sensitive information via MITM attacks.

💡 Fix: Use HTTPS URLs for service communication and enforce TLS verification.


19. SEC-027 (CWE-285) 🟡 MEDIUM

📁 go-service/internal/activity/tracker.go (line 143)
🏷️ Category: Auth

func (t *Tracker) DeleteUserActivity(userID string) bool {

Destructive operation 'DeleteUserActivity' lacks any authorization or access control checks, enabling potential abuse if exposed via API.

💡 Fix: Enforce authorization checks at the caller boundary (e.g., ensure only the resource owner/admin can delete) and log deletions for audit.


20. SEC-028 (CWE-330) 🟡 MEDIUM

📁 go-service/internal/activity/tracker.go (line 155)
🏷️ Category: Crypto

return time.Now().Format("20060102150405") + "-" + string(rune(counter))

Predictable ID generation using timestamp and incremental counter is not suitable for identifiers expected to be unguessable.

💡 Fix: Use a cryptographically-secure random UUID (e.g., github.com/google/uuid) for IDs if they need to be unguessable.


⚠️ 20 more vulnerabilities not shown. Address these issues first, then run /security-scan again.


🛡️ Security scan powered by Codity.ai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants