Outcome
Read the most recent stored voice-preset audit entries for the selected workspace. These records describe preset changes; they are not a provider delivery log or a full version history.
Action: app_topolo_socialize.brand_voice.audit.list.
GET /api/brand-voice/audit
Before you start
Verify the original credential, production environment and intended organization. Discover and bind an actually granted canonical Socialize workspace separately from action input. A preset/audit id is not a workspace id; never forge identity or switch principal after refusal.
This route resolves getBrandForVoice through resolveBrandId before the handler. Omitted workspace selection follows verified default resolution; a refused named workspace is not silently replaced. Original API-key bindings narrow grants. Workspace authorization may synchronize the local brand mirror even for declared read-only actions.
Published permission: app_topolo_socialize.analytics:read. Discover current concrete resource/permission eligibility with the original credential.
Request
{
"limit": 20
}
Keep the actual workspace binding separate from these fields. Validate and plan against the current discovered contract before the read.
Effects and response semantics
Published permission is app_topolo_socialize.analytics:read. The handler parses query limit with default50; current action validation accepts positive integer limits up to9007199254740991. Choose a modest actual limit appropriate to the read; no smaller service-enforced cap is established by this source.
The repository selects brand_voice_audit_log rows WHERE workspace_id=? ORDER BY created_at DESC LIMIT?. There is no secondary id ordering, cursor/offset, total/count or hasMore. Repeating the same limit rereads recent rows rather than fetching a next page; tied times and concurrent changes are not snapshot-stable.
Normal output is {success:true,logs:[rawRow,...]}. This method returns SQL row names: id,workspace_id,preset_id,action,actor_id,changes,created_at. It does not convert them into camelCase saved-preset records, hydrate actor display names or resolve current permissions.
The producer writes changes as JSON.stringify(changes) or null. The read leaves that value as a string/null, not an already parsed object or a before/after diff. A logged update can hold the supplied input rather than a complete record snapshot; interpret its actual content carefully.
Actions represented by the source row type are create,update,delete,set_default; preset_id may be null. An audit row is evidence of a stored application event only. This recent limited read does not prove exhaustive mutation history, a transactionally inseparable audit trail, successful provider delivery, unchanged current state or current actor entitlement.
The audit read itself does not write audit entries, change presets/defaults, generate content or call a model/provider. Preceding original-principal workspace authorization may synchronize local mirror state. The route has no local catch around getAuditLog; an exception uses outer handling, not a successful empty logs array or a documented exact handler-specific500 carrier.
Complete worked responses
A recent stored name-change audit entry
Complete source-derived synthetic/unrun row using the source-declared seven fields. Assumes this stored event exists in the verified fixture workspace; no update/audit/business call occurred. The changes value is the supplied-input JSON string, not a fabricated full before/after diff.
Input:
{
"limit": 20
}
Response:
{
"success": true,
"logs": [
{
"id": "audit_fixture_name",
"workspace_id": "ws_fixture_brand",
"preset_id": "voice_fixture_saved",
"action": "update",
"actor_id": "usr_fixture_author",
"changes": "{\"name\":\"Fixture renamed voice\"}",
"created_at": "2026-10-02 09:00:00"
}
]
}
Inspect raw workspace_id and action, retain changes as a string, and do not infer the preset’s current value or provider outcome.
No audit rows returned
Synthetic source-derived/unrun. Assumes the authorized query returns no stored rows; it does not simulate an Auth/storage refusal as empty success.
Input:
{
"limit": 20
}
Response:
{
"success": true,
"logs": []
}
Treat this as an empty recent scoped result; it is not complete-history, absence-of-mutation or provider evidence.
Refusals
{"limit": 0} is a local-preflight invalid-input example: the current schema requires a positive integer. It is not a simulated HTTP response, a resource probe or permission to send malformed input. Correct the actual field error before transport.
A missing-brand400 guard exists defensively in the handler, but the normal dispatcher resolves getBrandForVoice first. Omitted selection resolves a verified default or is refused earlier; a named-workspace refusal must not be described as that guard response. Outer Auth/workspace/dependency refusals can use a different carrier. Preserve actual status/code/request id; no precise localized message or live refusal capture is invented here.
Verify and recover
Compare raw workspace_id on every row to the intended verified workspace. Preserve audit id, preset_id, action and actor_id without substituting user display labels or present-day roles.
Keep changes as the returned JSON string/null and parse only deliberately for interpretation; do not treat it as a complete prior/current state. A deleted preset can legitimately have a retained audit identifier.
Check ordering/limit against the actual returned rows, while recognizing there is no total, next-page token or stable snapshot. Empty logs means no rows returned for this scoped query, not proof that no change ever occurred.
No automatic compensation is defined for possible authorization-side mirror synchronization. This read does not authorize a preset/audit mutation. Preserve the actual scope/query/request evidence and resolve the specific permission, storage or malformed-data issue through its owner before another authorized read; do not erase or fabricate history.
Change log
- 2026-10-21: Added source-qualified request, actual ordering/projection/limit behavior and complete synthetic/unrun response examples. Source review does not certify serving deployment, runtime data or provider outcomes; no application imports/tests/business/model/provider calls were performed.