cms.c2sgmbh/src/collections/Users.ts
Martin Porwoll 358920f442 feat(Community): add Community Management Phase 1
- Add 5 new collections: SocialPlatforms, SocialAccounts,
  CommunityInteractions, CommunityTemplates, CommunityRules
- Add communityRole field to Users collection
- Add YouTube API client for comment sync
- Add Claude AI service for sentiment analysis
- Add API endpoints: /api/community/sync-comments, /api/community/reply
- Add communityAccess.ts for role-based access control
- Add migrations for all new tables and community_role enum fix

Fix: Make audit hooks non-blocking to prevent user save timeout

Dependencies: @anthropic-ai/sdk, googleapis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 16:13:03 +00:00

111 lines
3.2 KiB
TypeScript

import type { CollectionConfig, Access } from 'payload'
import { auditUserAfterChange, auditUserAfterDelete } from '../hooks/auditUserChanges'
import {
auditAfterLogin,
auditAfterLogout,
auditAfterForgotPassword,
} from '../hooks/auditAuthEvents'
// Users können ihren eigenen Account bearbeiten
const canUpdateOwnAccount: Access = ({ req: { user }, id }) => {
// Super Admins können alle User bearbeiten
if (user?.isSuperAdmin) {
return true
}
// User können ihren eigenen Account bearbeiten
if (user?.id && id && String(user.id) === String(id)) {
return true
}
// Ansonsten Multi-Tenant Access Control
return true
}
export const Users: CollectionConfig = {
slug: 'users',
admin: {
useAsTitle: 'email',
},
access: {
// Erlaubt Benutzern, ihren eigenen Account zu aktualisieren
update: canUpdateOwnAccount,
},
auth: {
// Cookie-Konfiguration für Production hinter Reverse-Proxy (Cloudflare/Caddy)
cookies: {
sameSite: 'Lax',
secure: process.env.NODE_ENV === 'production',
domain: undefined, // Automatisch vom Browser gesetzt
},
// Sicherheitseinstellungen
lockTime: 10 * 60 * 1000, // 10 Minuten Lock nach max. Fehlversuchen
maxLoginAttempts: 5,
tokenExpiration: 7200, // 2 Stunden
},
hooks: {
afterChange: [auditUserAfterChange],
afterDelete: [auditUserAfterDelete],
afterLogin: [auditAfterLogin],
afterLogout: [auditAfterLogout],
afterForgotPassword: [auditAfterForgotPassword],
},
fields: [
{
name: 'isSuperAdmin',
type: 'checkbox',
label: 'Super Admin',
defaultValue: false,
admin: {
description: 'Super Admins haben Zugriff auf alle Tenants und können neue Tenants erstellen.',
position: 'sidebar',
},
},
// YouTube Operations Hub Felder
{
name: 'youtubeRole',
type: 'select',
label: 'YouTube-Rolle',
admin: {
position: 'sidebar',
description: 'Rolle im YouTube Operations Hub',
},
options: [
{ label: 'Kein Zugriff', value: 'none' },
{ label: 'Viewer (nur Lesen)', value: 'viewer' },
{ label: 'Editor (Schnitt)', value: 'editor' },
{ label: 'Producer (Produktion)', value: 'producer' },
{ label: 'Creator (Inhalte)', value: 'creator' },
{ label: 'Manager (Vollzugriff)', value: 'manager' },
],
defaultValue: 'none',
},
{
name: 'youtubeChannels',
type: 'relationship',
relationTo: 'youtube-channels',
hasMany: true,
label: 'YouTube-Kanäle',
admin: {
position: 'sidebar',
description: 'Zugewiesene YouTube-Kanäle',
condition: (data) => data?.youtubeRole && data.youtubeRole !== 'none',
},
},
// Community Management Felder
{
name: 'communityRole',
type: 'select',
label: 'Community-Rolle',
defaultValue: 'none',
options: [
{ label: 'Kein Zugriff', value: 'none' },
{ label: 'Viewer (nur Lesen)', value: 'viewer' },
{ label: 'Moderator', value: 'moderator' },
{ label: 'Manager (Vollzugriff)', value: 'manager' },
],
admin: {
position: 'sidebar',
description: 'Zugriff auf Community Management Features',
},
},
],
}