All notable changes to utopia-php/audit are documented in this file.
utopia-php/querybumped from0.1.*to0.3.*(locked at 0.3.3).setup()builds its DDL throughUtopia\Query\Schema\ClickHouseinstead of hand-assembled SQL. Column types,LowCardinality(...)/Nullable(...)wrapping, bloom-filter indexes, engine,ORDER BY,PARTITION BYandSETTINGSare all emitted by the schema builder. The retentionMODIFY TTL/REMOVE TTLstatements are unchanged.find(),count(),getById(),createBatch()andcleanup()build their SQL throughUtopia\Query\Builder\ClickHouse. Positional bindings are rewritten to typed{paramN:Type}ClickHouse placeholders from a column → type map derived fromgetAttributes().createBatch()usesBuilder\ClickHouse::bulkInsert(Format::JSONEachRow, …)to emit theINSERT … FORMAT JSONEachRowenvelope and serialize the body.Query::getMethod()now returns theUtopia\Query\Methodenum (upstream 0.3 change).Utopia\Audit\Querycontinues to expose the legacyTYPE_*string constants, which map to the same string values.
Filter semantics are unchanged: contains / notContains remain substring
matches (now compiled to ClickHouse position(col, ?) > 0 / = 0 rather than
LIKE '%needle%', which also removes the need for wildcard escaping).
The ClickHouse adapter now stores the parsed user-agent OS / client / device dimensions as dedicated optional columns (mirrors the usage events schema).
Loggetters for ClickHouse-backed reads:getOsCode(),getOsName(),getOsVersion(),getClientType(),getClientCode(),getClientName(),getClientVersion(),getClientEngine(),getClientEngineVersion(),getDeviceName(),getDeviceBrand(),getDeviceModel().
LowCardinality(Nullable(String))—osCode,osName,clientType,clientCode,clientName,clientEngine,deviceName,deviceBrand(bounded name/code/type dimensions).Nullable(String)—osVersion,clientVersion,clientEngineVersion,deviceModel(high-cardinality version/model strings, mirroringsdkVersion).
All columns are optional (required = false) so createBatch() never throws when a
caller omits them. Newly created tables include the columns automatically via setup().
setup() only issues CREATE TABLE IF NOT EXISTS, so existing tables do not gain the
columns automatically — apply them with an ALTER TABLE ... ADD COLUMN IF NOT EXISTS
migration.
The ClickHouse adapter now stores two additional optional columns capturing the SDK that produced an audit event:
Log::getSdk()andLog::getSdkVersion()getters for ClickHouse-backed log reads.
- Column
sdkLowCardinality(Nullable(String))— SDK name (e.g.web,flutter,console,cli); low-cardinality, optional. - Column
sdkVersionNullable(String)— SDK version (e.g.14.0.0); high-cardinality, optional. - Index
_key_sdk— bloom-filter index on thesdkcolumn.
Both columns are optional (required = false) so createBatch() never throws when a
caller omits them. Newly created tables include the columns automatically via setup().
setup() only issues CREATE TABLE IF NOT EXISTS, so existing tables do not gain the
columns automatically — apply them with an ALTER TABLE ... ADD COLUMN IF NOT EXISTS
migration.
The ClickHouse adapter now stores its principal columns under "actor" terminology:
actorId, actorType, actorInternalId. The shared SQL base, the Database adapter,
and the public Audit API are unchanged — Database-backed audit logs continue to use
userId.
This is a non-breaking change for callers of the public API. Audit::log($userId, ...),
Audit::getLogsByUser(...), Audit::countLogsByUser(...), and the equivalent
*ByUserAndEvents methods all keep their original signatures. The ClickHouse adapter
translates the legacy userId array key and Query::equal('userId', ...) filter
internally to the renamed actorId column.
Log::getActorId(),Log::getActorType(),Log::getActorInternalId()getters for ClickHouse-backed log reads.Loginstances returned by the ClickHouse adapter expose bothactorId/actorType/actorInternalId(canonical) anduserId/userType/userInternalId(legacy mirror) attribute keys so existing code paths continue to work.
- Column
userId→actorId - Column
userType→actorType - Column
userInternalId→actorInternalId - Index
idx_userId_event→idx_actorId_event - Index
_key_user_type→_key_actor_type - Index
_key_user_internal_id→_key_actor_internal_id - Index
_key_user_internal_and_event→_key_actor_internal_and_event
ClickHouse audit tables will be recreated by setup() with the new column names.
Existing ClickHouse audit data is not preserved automatically — this is acceptable
because the activity-events surface backed by this schema is not yet in public use.
If preservation is needed, run ALTER TABLE ... RENAME COLUMN for each renamed
column before redeploying.
No migration is required for Database-backed audit logs. The Database adapter
continues to write and read userId columns and indexes unchanged.
See git history.