PHPackages                             cla/generate-audit-report - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. cla/generate-audit-report

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

cla/generate-audit-report
=========================

Multi-step AI audit report generation workflow for Laravel applications

02↑2900%PHP

Since Jun 10Pushed todayCompare

[ Source](https://github.com/ayaashraf-cla/generate-audit-report)[ Packagist](https://packagist.org/packages/cla/generate-audit-report)[ RSS](/packages/cla-generate-audit-report/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

cla/generate-audit-report
=========================

[](#clagenerate-audit-report)

A Laravel package that runs a multi-step AI audit workflow against any Eloquent model and its uploaded documents, then produces a scored compliance report.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11 or 12
- [`ayaashraf/laravel-rag`](https://github.com/ayaashraf-cla/laravelRag) — document storage, text extraction, and vector search
- PostgreSQL + pgvector extension (for vector embeddings)
- A Google Gemini API key (or any provider supported by `laravel/ai`)

---

Quick Start
-----------

[](#quick-start)

```
use Cla\GenerateAuditReport\Facades\GenerateAuditReport;

$session = GenerateAuditReport::for($contract)
    ->documents($contract->documents()->where('status', 'processed')->get())
    ->prompt("Evaluate this contract for regulatory compliance.\n\nFocus areas:\n- Data handling clauses\n- Liability terms\n- Termination conditions")
    ->language('en')
    ->initiatedBy(auth()->id())
    ->generate();

// $session->id is available immediately
// the report is generated asynchronously on the queue
```

---

Installation Overview
---------------------

[](#installation-overview)

1. [Install and configure `ayaashraf/laravel-rag`](#step-1--install-ayaashraflaravel-rag)
2. [Add required `.env` variables](#step-2--environment-variables)
3. [Install `cla/generate-audit-report`](#step-3--install-clagenerateauditreport)
4. [Run migrations and publish config](#step-4--run-migrations--publish-config)
5. [Start the queue worker](#step-5--start-the-queue-worker)
6. [Extend `AuditSession` with your app's relationships](#step-6--extend-auditsession)

---

Step 1 — Install `ayaashraf/laravel-rag`
----------------------------------------

[](#step-1--install-ayaashraflaravel-rag)

```
composer require ayaashraf/laravel-rag:dev-main --with-all-dependencies
```

### Dual-database architecture

[](#dual-database-architecture)

The RAG package uses two database connections:

ConnectionPurposeEngineDefault (`mysql`)`documents` table — file metadataMySQL / MariaDB`pgsql_vector``document_chunks` table — vector embeddingsPostgreSQL + pgvectorAdd the second connection in `config/database.php`:

```
'pgsql_vector' => [
    'driver'   => 'pgsql',
    'host'     => env('VECTOR_DB_HOST', '127.0.0.1'),
    'port'     => env('VECTOR_DB_PORT', '5432'),
    'database' => env('VECTOR_DB_DATABASE', 'vector_db'),
    'username' => env('VECTOR_DB_USERNAME', 'postgres'),
    'password' => env('VECTOR_DB_PASSWORD', ''),
    'charset'  => 'utf8',
    'schema'   => 'public',
],
```

Enable the pgvector extension on your PostgreSQL instance:

```
CREATE EXTENSION IF NOT EXISTS vector;
```

### Publish RAG config and run migrations

[](#publish-rag-config-and-run-migrations)

```
php artisan vendor:publish --tag=rag-config
php artisan vendor:publish --tag=rag-views
php artisan vendor:publish --tag=rag-migrations
php artisan migrate
```

### Attach documents to a model

[](#attach-documents-to-a-model)

Add the `HasDocuments` trait to any model that owns uploaded files:

```
use AyaAshraf\LaravelRag\Traits\HasDocuments;

class Contract extends Model
{
    use HasDocuments;
}
```

This adds `documents()`, `visibleDocuments()`, and `hiddenDocuments()` relationships.

### Upload documents via the Livewire uploader

[](#upload-documents-via-the-livewire-uploader)

```

```

Accepted formats: **PDF, DOCX, TXT, XLS, XLSX, CSV** (max 100 MB, up to 10 files at once).

Document statuses:

StatusMeaning`queued`Waiting for the queue worker`processing`Job running`processed`Ready for audit evidence retrieval`empty`File had no extractable text`failed`Extraction or embedding errorOnly `processed` documents are used during an audit.

---

Step 2 — Environment variables
------------------------------

[](#step-2--environment-variables)

```
# Primary database (MySQL)
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=your_app_db

# Vector database (PostgreSQL + pgvector)
VECTOR_DB_HOST=127.0.0.1
VECTOR_DB_PORT=5432
VECTOR_DB_DATABASE=your_vector_db
VECTOR_DB_USERNAME=postgres
VECTOR_DB_PASSWORD=secret

# AI / embeddings
GEMINI_API_KEY=your_key_here
EMBEDDING_PROVIDER=gemini
RAG_VECTOR_CONNECTION=pgsql_vector
RAG_CHAT_MODEL=gemini-2.5-flash
EMBEDDING_DIMENSIONS=1536

 OR
OPENAI_API_KEY=your_key_here
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_DIMENSIONS=1536

RAG_CHAT_PROVIDERS=openai
RAG_CHAT_MODEL=gpt-4.1-mini
# Audit workflow
AUDIT_QUEUE=audit-workflow
QUEUE_CONNECTION=database
```

---

Step 3 — Install `cla/generate-audit-report`
--------------------------------------------

[](#step-3--install-clagenerate-audit-report)

```
composer require cla/generate-audit-report:dev-main --with-all-dependencies
```

The service provider is auto-discovered. The `GenerateAuditReport` facade alias is registered automatically at boot — no entry needed in `config/app.php`.

---

Step 4 — Run migrations &amp; publish config
--------------------------------------------

[](#step-4--run-migrations--publish-config)

```
# Package migrations are loaded automatically — just run migrate
php artisan migrate

# Publish audit config for customisation (optional)
php artisan vendor:publish --tag=audit-config

# Publish Livewire progress view for customisation (optional)
php artisan vendor:publish --tag=audit-views
```

Migrations create three tables: `audit_sessions`, `audit_reports`, `audit_step_logs`.

### Full config reference

[](#full-config-reference)

```
// config/audit.php
return [
    'chat' => [
        'provider' => env('RAG_CHAT_PROVIDERS', 'gemini'),
        'model'    => env('RAG_CHAT_MODEL', 'gemini-2.5-flash'),
        'timeout'  => env('RAG_CHAT_TIMEOUT', 40),
    ],

    'arabic_min_similarity'  => env('RAG_ARABIC_MIN_SIMILARITY', 0.30),
    'english_min_similarity' => env('RAG_ENGLISH_MIN_SIMILARITY', 0.45),
    'max_search_results'     => env('RAG_MAX_SEARCH_RESULTS', 10),
    'candidate_limit'        => env('RAG_CANDIDATE_LIMIT', 8),
    'top_k'                  => env('RAG_TOP_K', 4),
    'max_context_chars'      => env('RAG_MAX_CONTEXT_CHARS', 12000),
    'max_chunk_chars'        => env('RAG_MAX_CHUNK_CHARS', 3000),

    'queue' => env('AUDIT_QUEUE', 'audit-workflow'),
];
```

---

Step 5 — Start the queue worker
-------------------------------

[](#step-5--start-the-queue-worker)

Both the RAG document processing and the audit workflow run on the queue:

```
# Single worker covering all queues
php artisan queue:listen --tries=1 --timeout=0

# Or separate workers per queue
php artisan queue:listen --queue=default --tries=1 --timeout=0        # ProcessDocumentForRag
php artisan queue:listen --queue=audit-workflow --tries=1 --timeout=0 # RunAuditWorkflow
```

`RunAuditWorkflow` has a built-in 600-second timeout, 2 retries, and a 30-second backoff. On exhaustion, `AuditSession::markFailed()` is called automatically.

---

Step 6 — Extend `AuditSession`
------------------------------

[](#step-6--extend-auditsession)

The base `AuditSession` model has no knowledge of your app's relationships. Extend it to add whatever associations your application needs:

```
namespace App\Models;

class AuditSession extends \Cla\GenerateAuditReport\Models\AuditSession
{
    public function subject()
    {
        return $this->auditable(); // polymorphic — resolves to the audited model
    }

    public function initiator()
    {
        return $this->belongsTo(User::class, 'initiated_by');
    }
}
```

> This step is optional if you only access `$session` through the base model.

---

Builder API Reference
---------------------

[](#builder-api-reference)

### `GenerateAuditReport::for(Model $model)`

[](#generateauditreportformodel-model)

Sets the subject model. Any Eloquent model is accepted — the polymorphic `auditable_type` / `auditable_id` columns are populated automatically.

```
GenerateAuditReport::for($contract)
GenerateAuditReport::for($vendor)
GenerateAuditReport::for($employee)
```

### `->documents(Collection $documents)`

[](#-documentscollection-documents)

The `Document` collection to audit against. Pass only `status = 'processed'` documents, or pass all and let the retrieval step filter:

```
->documents($contract->documents()->where('status', 'processed')->get())
```

If omitted, no document evidence is retrieved and the report is based on the prompt alone.

### `->prompt(string $prompt)`

[](#-promptstring-prompt)

The context text the AI uses to understand what is being audited. Use line breaks to separate distinct topics — the orchestrator splits the prompt into search queries for RAG retrieval, so multi-paragraph prompts retrieve more diverse evidence:

```
->prompt(
    "Compliance audit for: {$contract->title}\n\n" .
    "Counterparty: {$contract->vendor->name}\n\n" .
    "Areas to evaluate:\n" .
    "- Data processing and GDPR obligations\n" .
    "- SLA commitments and penalty terms\n" .
    "- Termination and exit conditions"
)
```

### `->language(string $language)`

[](#-languagestring-language)

Audit language. Accepted values: `'en'` (default), `'ar'`.

Controls RAG similarity thresholds (Arabic: 0.30, English: 0.45) and the language of AI-generated prose.

### `->initiatedBy(int $userId)`

[](#-initiatedbyint-userid)

Records which user triggered the audit. Defaults to `auth()->id()` if omitted.

### `->generate()`

[](#-generate)

Creates the `AuditSession`, persists all context, and dispatches `RunAuditWorkflow` to the queue. Returns the session immediately — the report is generated asynchronously.

---

Complete Controller Example
---------------------------

[](#complete-controller-example)

```
use Cla\GenerateAuditReport\Facades\GenerateAuditReport;

class ContractAuditController extends Controller
{
    public function store(Contract $contract): RedirectResponse
    {
        $session = GenerateAuditReport::for($contract)
            ->documents($contract->documents()->where('status', 'processed')->get())
            ->prompt($this->buildPrompt($contract))
            ->language($contract->language ?? 'en')
            ->initiatedBy(auth()->id())
            ->generate();

        return redirect()->route('admin.audits.show', $session->id);
    }

    private function buildPrompt(Contract $contract): string
    {
        return implode("\n\n", [
            "Contract compliance review: {$contract->reference_number}",
            "Vendor: {$contract->vendor->name}",
            "Effective: {$contract->effective_date->toDateString()}",
            "Compliance areas:\n- " . implode("\n- ", $contract->compliance_areas),
        ]);
    }
}
```

---

Audit Workflow
--------------

[](#audit-workflow)

The job runs five sequential steps. Each step writes an `AuditStepLog` checkpoint — the workflow is **idempotent on retry**, resuming from the last completed step.

StepWhat it does1 — Analyze ContextStructures the provided context for AI reasoning; extracts risk signals and key topics2 — Retrieve EvidenceSemantic search (RAG) over uploaded documents to find relevant chunks2b — Readiness checkValidates evidence sufficiency; triggers supplemental retrieval if needed3 — Compare EvidenceCross-references context against retrieved evidence; identifies gaps and contradictions4 — Generate FindingsProduces compliance score, risk level, and detailed findings5 — Generate ReportProduces the final prose report with executive summary and recommendations---

Report Output
-------------

[](#report-output)

`AuditReport` is available after the session status becomes `completed`:

```
$session = AuditSession::with('report')->find($sessionId);

$report = $session->report;

$report->compliance_score;   // int, e.g. 78
$report->risk_level;         // 'low' | 'medium' | 'high' | 'critical'
$report->executive_summary;  // prose string
$report->findings;           // array of findings
$report->recommendations;    // array of remediation steps
$report->evidence_references; // retrieved chunks used as evidence
$report->document_stats;     // structured stats if a spreadsheet was uploaded
$report->document_summary;   // prose summary of uploaded documents
```

---

Real-Time Progress
------------------

[](#real-time-progress)

```

```

PropertyTypeDescription`$status`string`pending` / `running` / `completed` / `failed``$currentStep`int0–5`$percent`int0–100`$label`stringCurrent step label`$complete`bool`true` when finished`$failed`bool`true` on failure`$error`string|nullError message if failed`$stepLogs`arrayCompleted step details (duration, token usage)---

Document Profiling
------------------

[](#document-profiling)

When a document is uploaded, the package automatically dispatches a `ProfileDocument` job that:

1. Detects the file type (CSV, XLSX, or unstructured)
2. Analyses spreadsheet structure (sheets, columns, row count) for CSV/XLSX
3. Generates a bilingual (AR/EN) prose summary via AI
4. Stores the result as `document_profile` (JSON) and `summary_en` / `summary_ar` on the `Document` model

These are injected into the audit context before evidence retrieval so the AI understands each document's content and structure.

---

Retrying a Failed Audit
-----------------------

[](#retrying-a-failed-audit)

```
php artisan queue:retry all      # retry all failed jobs
php artisan queue:retry      # retry one specific job
```

The orchestrator skips any step that already completed successfully on the previous attempt.

---

Troubleshooting
---------------

[](#troubleshooting)

**`GenerateAuditReport` class not found**Run `php artisan config:clear` and restart your queue worker. The facade alias is registered at boot via the service provider.

**`__PHP_Incomplete_Class` on the queue worker**The worker started before `composer update` ran. Restart it.

**`Class "Cla\GenerateAuditReport\..." not found`**Run `composer update cla/generate-audit-report` then `php artisan package:discover`.

**No evidence retrieved (chunks = 0)**Confirm the documents you passed have `status = 'processed'` and that their `document_chunks` exist in the pgvector DB. Verify the `pgsql_vector` connection is reachable and the `vector` extension is installed.

**Report generated but findings are empty**The AI received the context but found nothing to flag. Check that the prompt describes specific compliance areas and that at least some chunks were retrieved — inspect the `AuditStepLog` for step 2's `chunk_count`.

**Audit fails immediately**Check the `error_message` on the `AuditSession` and the Laravel log. Most common causes: missing `GEMINI_API_KEY`, unreachable pgvector DB, or no processed documents.

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance65

Regular maintenance activity

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/285701252?v=4)[ayaashraf-cla](/maintainers/ayaashraf-cla)[@ayaashraf-cla](https://github.com/ayaashraf-cla)

---

Top Contributors

[![ayaashraf-cla](https://avatars.githubusercontent.com/u/285701252?v=4)](https://github.com/ayaashraf-cla "ayaashraf-cla (5 commits)")

### Embed Badge

![Health badge](/badges/cla-generate-audit-report/health.svg)

```
[![Health](https://phpackages.com/badges/cla-generate-audit-report/health.svg)](https://phpackages.com/packages/cla-generate-audit-report)
```

###  Alternatives

[mhor/php-mediainfo

PHP wrapper around the mediainfo command

120589.5k7](/packages/mhor-php-mediainfo)[gpolguere/path-to-regexp-php

PHP port of https://github.com/component/path-to-regexp

2211.8k2](/packages/gpolguere-path-to-regexp-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
