›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-checklist
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Templates and versions
  • Items and sections
  • Checklist lifecycle
  • Answers and evidence
  • Conditional rules
  • Scoring
  • Recurring schedules
  • Audit history

Operations

  • Author a template
  • Run a checklist
  • Create a schedule
  • Customize notifications
  • Export and report
  • Verify audit history
  • Composing with sibling packages

Reference

  • Configuration
  • Builder API
  • Models and scopes
  • Events and notifications
  • Console commands
  • Enums and contracts
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Templates and versions
  • Items and sections
  • Checklist lifecycle
  • Answers and evidence
  • Conditional rules
  • Scoring
  • Recurring schedules
  • Audit history

Operations

  • Author a template
  • Run a checklist
  • Create a schedule
  • Customize notifications
  • Export and report
  • Verify audit history
  • Composing with sibling packages

Reference

  • Configuration
  • Builder API
  • Models and scopes
  • Events and notifications
  • Console commands
  • Enums and contracts
  • Testing
  • Troubleshooting

byrcsc/laravel-checklist · 1.x

Export and report.

Build ordered checklist data for rendering and query stored operational metrics without recomputing history.

An export flattens one checklist into ordered data you can hand to a Blade view, a JSON response, or a PDF renderer. It carries the recorded answers, evidence references, scores, and chain status. Reports and query scopes summarize many runs from the results already stored on them.

1. Eager-load and build an export

use ByRcsc\LaravelChecklist\Models\Checklist;

$checklist = Checklist::query()
    ->withExportRelations()
    ->findOrFail($id);

$export = $checklist->toExport();
$data = $export->toArray();
$json = json_encode($export, JSON_THROW_ON_ERROR);

withExportRelations() loads the frozen template, ordered structure, responses, evidence, people, subject, schedule, and action count. The export then verifies the audit chain with one streamed history walk.

The top level contains checklist and template identity, status, subject, assignee, timestamps, score fields, root answers, nested sections, review, and chain status.

Each answer contains the frozen item fields, answer state, value, note, applicability, answerer, time, evidence, and signatures. Hidden answers remain present with is_applicable: false.

2. Render files through application policy

Evidence entries contain disk and path, not a public URL. Generate an authorized URL at render time:

use Illuminate\Support\Facades\Storage;

$url = Storage::disk($reference->disk)
    ->temporaryUrl($reference->path, now()->addMinutes(10));

$export->signatures() collects every signature from root and nested answers for renderers that place signatures in a separate section.

The package does not generate PDF files. Pass the array to Blade, a JSON API, or your chosen PDF renderer.

3. Render a PDF from the export

The package does not depend on a PDF renderer. Install one, then pass the export to a view:

composer require barryvdh/laravel-dompdf
use Barryvdh\DomPDF\Facade\Pdf;
use ByRcsc\LaravelChecklist\Models\Checklist;

$checklist = Checklist::query()->withExportRelations()->findOrFail($id);

return Pdf::loadView('checklists.pdf', ['export' => $checklist->toExport()])
    ->download("checklist-{$id}.pdf");

The view reads the export's public properties. Sections nest, so the section and answer partials each include themselves for children:

{{-- resources/views/checklists/pdf.blade.php --}}
<h1>{{ $export->templateName }} <small>v{{ $export->templateVersion }}</small></h1>

<p>
    Subject: {{ $export->subject ?? 'None' }}<br>
    Assigned to: {{ $export->assignee ?? 'Nobody' }}
</p>

<p>
    Status: {{ $export->status->value }}
    @if ($export->score !== null)
        (score: {{ number_format($export->score * 100, 1) }}%)
        @if ($export->passed !== null)
            ({{ $export->passed ? 'passed' : 'failed' }})
        @endif
    @endif
</p>

@if ($export->criticalFailed)
    <p><strong>A critical item failed.</strong></p>
@endif

@include('checklists.partials.answers', ['answers' => $export->answers])

@foreach ($export->sections as $section)
    @include('checklists.partials.section', ['section' => $section])
@endforeach

@if ($export->signatures())
    <h2>Signatures</h2>
    @foreach ($export->signatures() as $signature)
        <img src="{{ Storage::disk($signature->disk)->path($signature->path) }}" width="240">
    @endforeach
@endif

@if ($export->review->reviewed)
    <p>
        Reviewed by {{ $export->review->reviewer }}.
        Outcome: {{ $export->review->outcome }}.
    </p>
@endif

<p>
    Audit chain: {{ $export->chain->intact ? 'verified' : 'BROKEN: ' . $export->chain->reason }}
    ({{ $export->chain->actions }} actions)
</p>
{{-- resources/views/checklists/partials/section.blade.php --}}
<h2>{{ $section->name }}</h2>

@include('checklists.partials.answers', ['answers' => $section->answers])

@foreach ($section->sections as $child)
    @include('checklists.partials.section', ['section' => $child])
@endforeach
{{-- resources/views/checklists/partials/answers.blade.php --}}
@foreach ($answers as $answer)
    <p @class(['not-applicable' => ! $answer->isApplicable])>
        {{ $answer->label }}:
        {{ $answer->isAnswered ? json_encode($answer->value) : 'Not answered' }}
        @unless ($answer->isApplicable) <em>(not applicable)</em> @endunless

        @if ($answer->note)<br><em>{{ $answer->note }}</em>@endif

        @foreach ($answer->evidence as $file)
            <br><img src="{{ Storage::disk($file->disk)->path($file->path) }}" width="200">
        @endforeach
    </p>
@endforeach

Storage::disk()->path() reads the file from local disk, which suits a renderer running on the same machine. Use temporaryUrl() as shown above when the evidence disk is remote.

4. Filter checklist queries

Checklist::query()->pending();
Checklist::query()->inProgress();
Checklist::query()->completed();
Checklist::query()->reviewed();
Checklist::query()->overdue();
Checklist::query()->forSubject($vehicle);
Checklist::query()->forAssignee($driver);
Checklist::query()->forTemplate($template);
Checklist::query()->completedBetween($from, $to);

overdue() returns only pending and in-progress work whose due date has passed. Finished work may be late, but it is no longer overdue.

5. Run semantic reports

use ByRcsc\LaravelChecklist\Reporting\Reports;

$rates = Reports::completionRate($template);
$averages = Reports::averageScore($template);
$failed = Reports::mostFailedItems(limit: 20);
$overdue = Reports::overdueByAssignee();
$critical = Reports::criticalFailures($template);

Completion and average score return one row per template version. Average score uses the value stored at submission.

Most-failed items groups by lineage across versions and excludes not-applicable answers. It scans applicable answered responses in chunks because select failure depends on item configuration and cannot be expressed as one portable SQL predicate.

Reports return data objects with public readonly properties and toArray(). They do not cache or materialize summary tables.

What to read next

  • Models and scopes for exact query signatures.
  • Scoring for the meaning of stored scores and null results.
  • Audit history for what the export's chain block verifies.
PreviousCustomize notificationsNextVerify audit history
View source

On this page

  1. 1. Eager-load and build an export
  2. 2. Render files through application policy
  3. 3. Render a PDF from the export
  4. 4. Filter checklist queries
  5. 5. Run semantic reports
  6. What to read next