Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ jobs:
id: stan
run: |
set +e
vendor/bin/phpstan analyse --error-format=json --no-progress > phpstan.json 2>&1
vendor/bin/phpstan analyse --error-format=json --no-progress > phpstan.json
EXIT_CODE=$?

# Also run for GitHub format
vendor/bin/phpstan analyse --error-format=github --no-progress 2>&1 || true
vendor/bin/phpstan analyse --error-format=github --no-progress || true

ERRORS=$(jq '.totals.file_errors // 0' phpstan.json 2>/dev/null || echo "0")
echo "errors=${ERRORS}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -181,11 +181,11 @@ jobs:
id: psalm
run: |
set +e
vendor/bin/psalm --output-format=json --show-info=false > psalm.json 2>&1
vendor/bin/psalm --output-format=json --show-info=false > psalm.json
EXIT_CODE=$?

# Generate SARIF for GitHub Security
vendor/bin/psalm --output-format=sarif --show-info=false > psalm.sarif 2>&1 || true
vendor/bin/psalm --output-format=sarif --show-info=false > psalm.sarif || true

ERRORS=$(jq 'length' psalm.json 2>/dev/null || echo "0")
echo "errors=${ERRORS}" >> $GITHUB_OUTPUT
Expand All @@ -198,6 +198,14 @@ jobs:

exit $EXIT_CODE

- name: Debug Psalm Output
if: always()
run: |
echo "--- psalm.json ---"
cat psalm.json || echo "psalm.json not found"
echo "--- psalm.sarif ---"
cat psalm.sarif || echo "psalm.sarif not found"

- name: Upload Psalm SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
Expand Down Expand Up @@ -242,7 +250,7 @@ jobs:
id: fmt
run: |
set +e
OUTPUT=$(vendor/bin/pint --test --format=json 2>&1)
OUTPUT=$(vendor/bin/pint --test --format=json)
EXIT_CODE=$?
echo "$OUTPUT" > pint.json

Expand Down Expand Up @@ -292,7 +300,7 @@ jobs:
id: audit
run: |
set +e
composer audit --format=json > audit.json 2>&1
composer audit --format=json > audit.json
EXIT_CODE=$?

VULNS=$(jq '.advisories | to_entries | map(.value | length) | add // 0' audit.json 2>/dev/null || echo "0")
Expand Down
29 changes: 29 additions & 0 deletions AUDIT-DATABASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Database Query Optimization Audit

This document outlines the findings of a database query optimization audit.

## 1. Missing Indexes

### `activities` Table

**Finding:** The `activities` table, used by the `spatie/laravel-activitylog` package, was missing indexes on the polymorphic `subject` and `causer` columns. This can lead to slow queries when filtering activities by these relationships.

**Recommendation:** Add composite indexes to the `(subject_type, subject_id)` and `(causer_type, causer_id)` columns.

**Action Taken:** A migration has been created to add these indexes.

## 2. Environment and Dependencies

**Finding:** The project has conflicting dependencies, specifically with `vimeo/psalm`, which prevents the installation of development tools like Laravel Debugbar and blocks the execution of the test suite.

**Recommendation:** Resolve the dependency conflicts in `composer.json` to ensure a stable and consistent development environment. This is crucial for proper testing and debugging.

## 3. Further Analysis

The following files have been identified for further manual review to identify potential N+1 query problems, inefficient Eloquent patterns, and other query-related issues:

* `src/Mod/Trees/Models/TreeDonation.php`
* `src/Mod/Trees/Models/TreePlanting.php`
* `src/Mod/Trees/Models/TreePlantingStats.php`
* `src/Mod/Trees/Models/TreeReserve.php`
* `src/Mod/Trees/Controllers/Api/TreeStatsController.php`
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('activities', function (Blueprint $table) {
$table->index(['subject_type', 'subject_id'], 'subject_index');
$table->index(['causer_type', 'causer_id'], 'causer_index');
});
}

public function down(): void
{
Schema::table('activities', function (Blueprint $table) {
$table->dropIndex('subject_index');
$table->dropIndex('causer_index');
});
}
};
Loading