承接 wedevelopnl/audit-log 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

wedevelopnl/audit-log

Composer 安装命令:

composer require wedevelopnl/audit-log

包简介

Immutable, self-contained audit trail for Symfony and Doctrine.

README 文档

README

Immutable, self-contained audit trail for Symfony and Doctrine.

An audit record answers — durably and credibly — who did what, to what, when, from where, and what changed, and keeps answering it regardless of what later happens to the rest of the system. Records are immutable snapshots of a past fact: they survive deletion of the actor, the subject, and the producing code.

The package ships as a Symfony bundle: a framework-free core (value objects, the AuditEvent contract, the Recorder and read ports) plus Doctrine persistence and Symfony runtime adapters, pre-wired by the bundle. The core stays free of Symfony and Doctrine (ADR-0009).

Requirements

  • PHP 8.5+
  • Symfony 8.0 (framework-bundle, security-core, translation, and the components pulled in transitively)
  • Doctrine (dbal ^4, orm ^3.6, doctrine-bundle ^3.2)

Installation

composer require wedevelopnl/audit-log

There is no Flex recipe; register the bundle manually in config/bundles.php:

return [
    // ...
    WeDevelop\AuditLog\AuditLogBundle::class => ['all' => true],
];

The bundle auto-registers its Doctrine DBAL types and the AuditRecordEntity mapping. See docs/installation.md for the migration, the recommended append-only database grant, and the services you must provide.

Design

Three responsibilities are deliberately separated:

Responsibility Type Concern
Describe an act AuditEvent Pure data + phrasing. No clock, identity, or services.
Capture the moment Recorder Resolves time, actor, origin, subject label; freezes everything.
The durable read shape AuditRecord Immutable snapshot, interpretable without the producing code.
Query the trail RecordReader Paginated, filterable reads (AuditQueryAuditPage) for display.

The architecture derives from six governing properties — immutable, self-contained, faithful to the moment, attributable, intelligible, queryable. The rationale lives in the Architecture Decision Records.

Usage

Describe an auditable act by implementing AuditEvent (or extending AbstractAuditEvent for sane defaults):

use WeDevelop\AuditLog\Event\AbstractAuditEvent;
use WeDevelop\AuditLog\Event\Changeset;
use WeDevelop\AuditLog\Event\FieldChange;
use WeDevelop\AuditLog\Event\Subject;

final readonly class UserRoleChanged extends AbstractAuditEvent
{
    public function __construct(
        private string $userId,
        private string $from,
        private string $to,
    ) {
    }

    public function code(): string
    {
        return 'user.role_changed';
    }

    public function subject(): Subject
    {
        return new Subject(User::class, $this->userId);
    }

    public function changes(): Changeset
    {
        return new Changeset(FieldChange::of('role', $this->from, $this->to));
    }

    protected function parameters(): array
    {
        return ['from' => $this->from, 'to' => $this->to];
    }
}

Record it through the Recorder — the single write seam, autowired by the bundle. It captures the ambient strands of the moment (clock, acting principal, origin, subject label) and appends a frozen record:

$recorder->record(new UserRoleChanged($userId, 'member', 'admin'));

To attach human-readable subject labels, provide a SubjectLabeller (the default returns none); read the trail back through RecordReader. See docs/installation.md for wiring.

Sensitive fields are recorded as changed without their values:

new Changeset(FieldChange::redacted('password'));

License

BSD 3-Clause. See LICENSE. © 2026 WeDevelop.

统计信息

  • 总下载量: 309
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-3-Clause
  • 更新时间: 2026-06-01

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固