Repository navigation
feat(audit): Operate · Audit log page (Batch 4 / T402, PR-13) - #32
Merged
Merged
Conversation
…r + chain stub Implements @gocell/audit Batch 4 / T402: - package.json: deps, exports (./stores + ./views/audit), test scripts - vitest.config.ts + tsconfig.json: mirrors access cell setup - src/api/audit.ts: listAudit() + AuditEntry type (codegen-bound via HttpAuditListV1Response) - src/lib/hashChain.ts: pure verifyChain() — ok/broken/unavailable paths; ready for BR-006 - src/lib/auditClassify.ts: classifyActor() heuristic + groupByDay() + formatDayLabel() - src/stores/useAuditStore.ts: fetchList/loadMore/filteredEntries/entriesByDay/chainStatus - src/components/ActorPill.vue: aria-hidden dot + actorId label, variant via classifyActor - src/views/AuditView.vue: day-grouped master-detail, filter toolbar, quick-filter chips - 70 tests, all green; coverage statements/lines/branches/functions all ≥ 80% Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- apps/web: register /audit (PDP read:audit, fail-closed) as AppShellLayout child; lazy-load @gocell/audit/views/audit subpath; add @gocell/audit dep. - core i18n: add audit.log.* block (zh-CN + en-US) for the Audit log page. - router spec: assert /audit resolves nested with auth + PDP meta. Refs #15 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks done
…th isRecord guard - api/audit.ts: remove AuditListPage interface (a hand-written mirror of the HttpAuditListV1Response contract envelope); listAudit now returns the contract type directly. Enforces "契约类型必须来自 @gocell/contracts;不在业务包里手写后端 DTO". - stores/useAuditStore.ts: replace `as Record<string, unknown>` casts in chainStatus with an isRecord() type guard, honoring the existing "no `as` cast" comment and the unknown + 类型守卫 rule. Behavior unchanged; 74 audit tests pass, typecheck + lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
Author
六维度 Review(包边界 / Vue 模板 / TS / 包架构 / a11y / 性能 / 设计一致性)整体质量积极:包边界完全合规( 已修复(commit c5df867)
行为不变,typecheck / lint / 74 测试全绿。 评估后不改(登记说明)
结论:✅ 可合并。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch 4 / T402 — the Operate · Audit log page, first of the two PRs for #15 (audit cell; config+flags follow in PR-14, stacked on this branch).
New cell
@gocell/auditmirroring the@gocell/accessstructure: a tamper-evident audit trail with day-grouped entries, actor pills, quick filters, and a hash-chain integrity panel.api/audit.ts—listAudit()against/api/v1/audit/, cursor-paginated. Row typeAuditEntryis codegen-bound toHttpAuditListV1Response['data'][number](no hand-written DTO). LocalListAuditParamsdocumented as provisional pending a backend request schema.stores/useAuditStore.ts(audit.query) — list/loadMore, client-side three-dimensional filter (free-text + actor-kind + action-namespace),entriesByDaygrouping,chainStatusgetter.lib/hashChain.ts— pureverifyChain()(ok/broken/unavailable), fully tested, ready to activate when the backend exposes hash fields.lib/auditClassify.ts—classifyActor()(prefix heuristic),groupByDay().views/AuditView.vue+components/ActorPill.vue— V1-Linear chrome, tokens-only styling, semantic markup.Backend gaps (frontend-first per the #15 directive — graceful degradation, no fabricated data)
The contract delivers fewer fields than the design (
dev-audit.jsx). Handled by degrading, not faking:hash/prevHashrole=status), never a fake OK. Algorithm is implemented + tested, activates when fields ship.actorTypeclassifyActor()prefix heuristic; the rawactorIdis always the visible label, kind only drives the decorative dot.result/reason/actor.ip/actor.mfaListAuditParams; client-side filter over the loaded page.BR-006 (audit hash-chain + actor/result fields) will be filed against
ghbvf/gocell.Packages touched
@gocell/audit(new cell): api / store / lib / view / component / README / exports.@gocell/core: i18naudit.log.*block (zh-CN + en-US) — established pattern (access keys live here too).apps/web:/auditroute (PDPread:audit, fail-closed) +@gocell/auditdependency.packages/contracts/: not modified — consumed read-only.Test plan
pnpm -F @gocell/audit test --run— 70 tests passpnpm -F @gocell/audit test:coverage— 94.66% lines / 82.81% branches / 86.2% functions (≥80%)pnpm -w typecheck— clean (incl. en-USsatisfies MessageSchema)pnpm -w lint— 0 issuespnpm -w test --run— 49 files / 692 tests pass (incl. new/auditrouter assertion)Refs #15