PHPackages                             meita/journal-guard - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. meita/journal-guard

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

meita/journal-guard
===================

Guard and validate journal entries before they are posted to the ledger.

1.0.0(6mo ago)00MITPHPPHP ^8.2

Since Dec 21Pushed 6mo agoCompare

[ Source](https://github.com/EngMEita/JournalGuard)[ Packagist](https://packagist.org/packages/meita/journal-guard)[ RSS](/packages/meita-journal-guard/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (4)Versions (2)Used By (0)

meita/journal-guard
===================

[](#meitajournal-guard)

Guard and validate journal entries **before** they are posted to the ledger. Built for Laravel 10/11/12 with extensible rule classes and clear, human-readable errors.

Installation
------------

[](#installation)

```
composer require meita/journal-guard
php artisan vendor:publish --provider="Meita\\JournalGuard\\JournalGuardServiceProvider" --tag=config
```

Configuration
-------------

[](#configuration)

`config/journal-guard.php` ships with:

- `enabled`: toggle the guard.
- `mode`: `strict` (throws) or `warning` (returns warnings, no throw).
- `rules`: ordered list of rule classes.
- `account_model`, `period_model`, `currency_model`: optional model classes for built-in rules.
- `resolvers.account|period|currency`: optional callbacks to resolve accounts/periods/currency without coupling to models.
- `default_currency`, `enforce_default_currency`: enforce default currency when needed.

Example resolver registration:

```
app('config')->set('journal-guard.resolvers.account', function ($line, $entry) {
    // return model/array/bool to indicate active account
    return $line->accountId() === 100 ? (object) ['is_active' => true] : null;
});
```

Usage
-----

[](#usage)

### Validating a payload

[](#validating-a-payload)

```
use Meita\JournalGuard\Facades\JournalGuard;
use Meita\JournalGuard\Exceptions\JournalValidationException;

$payload = [
    'company_id' => 1,
    'branch_id' => 2,
    'currency' => 'SAR',
    'entry_date' => '2024-01-31',
    'reference' => 'JV-1001',
    'description' => 'Accruals',
    'lines' => [
        ['account_id' => 10, 'debit' => 1000, 'credit' => 0, 'description' => 'Expense'],
        ['account_id' => 200, 'debit' => 0, 'credit' => 1000, 'description' => 'Accrual'],
    ],
];

try {
    $result = JournalGuard::validate($payload); // returns ValidationResult on success
} catch (JournalValidationException $e) {
    // $e->errors() holds code/message/path tuples
}
```

### Warning mode

[](#warning-mode)

```
config(['journal-guard.mode' => 'warning']);
$result = JournalGuard::validate($payload);

if (!$result->passed()) {
    // $result->warnings() contains non-blocking issues
}
```

### Trait for services

[](#trait-for-services)

```
use Meita\JournalGuard\Traits\GuardsJournalEntries;

class JournalEntryService
{
    use GuardsJournalEntries;

    public function create(array $payload)
    {
        $this->guardJournalEntry($payload);
        // ...persist entry
    }
}
```

### Custom rules

[](#custom-rules)

Create a rule implementing `Meita\JournalGuard\Contracts\RuleInterface` and add it to the `rules` config array.

```
use Meita\JournalGuard\Contracts\RuleInterface;
use Meita\JournalGuard\DTO\JournalEntryDTO;
use Meita\JournalGuard\Exceptions\JournalValidationException;

class NoWeekendEntriesRule implements RuleInterface
{
    public function validate(JournalEntryDTO $entry): void
    {
        if ($entry->date()->isWeekend()) {
            throw new JournalValidationException([
                ['code' => 'weekend_block', 'message' => 'Weekend entries are not allowed.', 'path' => 'entry_date'],
            ]);
        }
    }
}
```

### Middleware-like usage

[](#middleware-like-usage)

```
public function store(Request $request)
{
    try {
        JournalGuard::validate($request->all());
    } catch (JournalValidationException $e) {
        return back()->withErrors($e->errors());
    }

    // continue to save...
}
```

Built-in rules
--------------

[](#built-in-rules)

- **BalancedRule**: total debit equals total credit; totals must be &gt; 0.
- **PositiveAmountsRule**: no negatives, no line with both debit and credit, no empty amounts.
- **AccountsActiveRule**: accounts exist and are active (via resolver or configured model).
- **ClosedPeriodRule**: entry date falls within an open period (resolver or model).
- **CurrencyRule**: currency allowed for the company and default currency enforcement.

Events
------

[](#events)

- `JournalValidating`
- `JournalValidated`
- `JournalRejected`

Hook into these with Laravel's event listeners to log, audit, or instrument validation.

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance67

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

195d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5915383ac10e7c148c23e142195199c8e7909acc2cda2003c26e688090956014?d=identicon)[EngMEita](/maintainers/EngMEita)

---

Top Contributors

[![EngMEita](https://avatars.githubusercontent.com/u/11925529?v=4)](https://github.com/EngMEita "EngMEita (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/meita-journal-guard/health.svg)

```
[![Health](https://phpackages.com/badges/meita-journal-guard/health.svg)](https://phpackages.com/packages/meita-journal-guard)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k8.4M96](/packages/mongodb-laravel-mongodb)[illuminate/view

The Illuminate View package.

13047.0M2.2k](/packages/illuminate-view)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[aimeos/laravel-nestedset

Nested Set Model for Laravel

3714.4k6](/packages/aimeos-laravel-nestedset)[rapidez/core

Rapidez Core

1823.5k72](/packages/rapidez-core)

PHPackages © 2026

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