feat(admin): add ActivityLog schema and isAdmin flag
Database changes: - Add ActivityLog model for comprehensive activity tracking - Track all user actions (auth, events, matches, admin) - Denormalized username for query performance - JSON metadata for flexibility - Multiple indexes for common filter patterns - Add isAdmin flag to User model for admin access control - Add activityLogs relation to User Schema pushed to database with prisma db push Created initial admin user: spotlight@radziel.com This is Phase 1 of Activity Log System implementation. Next phases: backend service, middleware, API endpoints, frontend UI.
This commit is contained in:
@@ -61,6 +61,9 @@ model User {
|
||||
recordingsDone Int @default(0) @map("recordings_done") // How many times this user recorded others
|
||||
recordingsReceived Int @default(0) @map("recordings_received") // How many times others recorded this user
|
||||
|
||||
// Admin flag
|
||||
isAdmin Boolean @default(false) @map("is_admin")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@ -73,6 +76,7 @@ model User {
|
||||
eventParticipants EventParticipant[]
|
||||
heats EventUserHeat[]
|
||||
recordingAssignments RecordingSuggestion[] @relation("RecorderAssignments")
|
||||
activityLogs ActivityLog[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -322,3 +326,42 @@ model MatchingRun {
|
||||
@@index([eventId, startedAt])
|
||||
@@map("matching_runs")
|
||||
}
|
||||
|
||||
// Activity logs for admin monitoring
|
||||
model ActivityLog {
|
||||
id Int @id @default(autoincrement())
|
||||
|
||||
// Core identification
|
||||
userId Int? @map("user_id") // NULL for system actions
|
||||
username String? @db.VarChar(50) // Denormalized for performance
|
||||
ipAddress String? @map("ip_address") @db.VarChar(45) // IPv4 or IPv6
|
||||
|
||||
// Action details
|
||||
action String @db.VarChar(50) // 'auth.register', 'match.create', etc.
|
||||
category String @db.VarChar(20) // 'auth', 'event', 'match', 'admin', 'chat'
|
||||
resource String? @db.VarChar(100) // Resource ID (e.g., 'event:123', 'match:abc')
|
||||
|
||||
// Contextual data
|
||||
method String? @db.VarChar(10) // HTTP method: GET, POST, PUT, DELETE
|
||||
path String? @db.VarChar(255) // API path
|
||||
metadata Json? // Flexible JSON for action-specific data
|
||||
|
||||
// Result tracking
|
||||
success Boolean @default(true) // Track failures too
|
||||
errorMessage String? @map("error_message") @db.Text
|
||||
|
||||
// Timestamp
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
// Relations
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
|
||||
// Indexes for performance
|
||||
@@index([userId, createdAt])
|
||||
@@index([action, createdAt])
|
||||
@@index([category, createdAt])
|
||||
@@index([createdAt(sort: Desc)]) // Most common query pattern
|
||||
@@index([username, createdAt]) // Search by username
|
||||
|
||||
@@map("activity_logs")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user