Implement Sprint 1 stories: collections, RBAC, audit logging, load testing

Complete 6 Sprint 1 stories for Epic 1 web migration infrastructure.

Portfolio Collection:
- Add 7 fields: title, slug, url, image, description, websiteType, tags
- Configure R2 storage and authenticated access control

Categories Collection:
- Add nameEn, order, textColor, backgroundColor fields
- Add color picker UI configuration

Posts Collection:
- Add excerpt with 200 char limit and ogImage for social sharing
- Add showInFooter checkbox and status select (draft/review/published)

Role-Based Access Control:
- Add role field to Users collection (admin/editor)
- Create adminOnly and authenticated access functions
- Apply access rules to Portfolio, Categories, Posts, Users collections

Audit Logging System (NFR9):
- Create Audit collection with timestamps for 90-day retention
- Add auditLogger utility for login/logout/content change tracking
- Add auditChange and auditGlobalChange hooks to all collections and globals
- Add cleanupAuditLogs job with 90-day retention policy

Load Testing Framework (NFR4):
- Add k6 load testing with 3 scripts: public-browsing, admin-operations, api-performance
- Configure targets: p95 < 500ms, error rate < 1%, 100 concurrent users
- Add verification script and comprehensive documentation

Other Changes:
- Remove unused Form blocks
- Add Header/Footer audit hooks
- Regenerate Payload TypeScript types
This commit is contained in:
2026-01-31 17:20:35 +08:00
parent 0846318d6e
commit 7fd73e0e3d
48 changed files with 19497 additions and 5261 deletions

View File

@@ -3,6 +3,7 @@ import type { CollectionConfig } from 'payload'
import { authenticated } from '../../access/authenticated'
import { authenticatedOrPublished } from '../../access/authenticatedOrPublished'
import { adminOrEditor } from '../../access/adminOrEditor'
import { auditChange } from '../../collections/Audit/hooks/auditHooks'
import { Archive } from '../../blocks/ArchiveBlock/config'
import { CallToAction } from '../../blocks/CallToAction/config'
import { Content } from '../../blocks/Content/config'
@@ -123,9 +124,9 @@ export const Pages: CollectionConfig<'pages'> = {
...slugField(),
],
hooks: {
afterChange: [revalidatePage],
afterChange: [revalidatePage, auditChange('pages')],
beforeChange: [populatePublishedAt],
afterDelete: [revalidateDelete],
afterDelete: [revalidateDelete, auditChange('pages')],
},
versions: {
drafts: {