Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ export function createAuthRouter(): Router {
email: user.email,
});

// Log login event
db.audit.log({
kind: "user_login",
message: `User ${user.email} logged in`,
userId: user.id,
severity: "info",
meta: { email: user.email, role: user.role },
});

// Return tokens
res.json({
success: true,
Expand Down Expand Up @@ -98,6 +107,9 @@ export function createAuthRouter(): Router {
});
}

// Get user from token before revoking
const payload = verifyAccessToken(accessToken);

// Get refresh token from body
const { refreshToken } = req.body;

Expand All @@ -109,6 +121,17 @@ export function createAuthRouter(): Router {
revokeToken(refreshToken);
}

// Log logout event
if (payload) {
db.audit.log({
kind: "user_logout",
message: `User ${payload.email} logged out`,
userId: payload.userId,
severity: "info",
meta: { email: payload.email },
});
}

res.json({
success: true,
message: "Logged out successfully",
Expand Down
40 changes: 40 additions & 0 deletions src/api/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ export function createTaskRouter(db: Database, queue: QueueAdapter, gate: Enforc
// Task is BLOCKED - do NOT queue, require human approval
db.updateTask(task.id, { status: "stopped", stop_score: gateDecision.stopScore });

// Log blocked task event
db.audit.log({
kind: "task_failed",
message: `Task "${task.title}" blocked by enforcement gate`,
taskId: task.id,
userId: (req as any).userId,
severity: "warn",
meta: { stopScore: gateDecision.stopScore, reasons: gateDecision.reasons },
});

return res.status(202).json({
id: task.id,
status: "BLOCKED",
Expand All @@ -74,6 +84,16 @@ export function createTaskRouter(db: Database, queue: QueueAdapter, gate: Enforc
// Task passed gate - queue for processing
await queue.add("process_task", { taskId: task.id });

// Log task created event
db.audit.log({
kind: "task_created",
message: `Task "${task.title}" created`,
taskId: task.id,
userId: (req as any).userId,
severity: "info",
meta: { priority: task.priority, assignee: task.assignee },
});

res.status(201).json({
id: task.id,
status: "pending",
Expand Down Expand Up @@ -111,6 +131,16 @@ export function createTaskRouter(db: Database, queue: QueueAdapter, gate: Enforc
// Work is BLOCKED - cannot complete task
db.updateTask(task.id, { status: "stopped", stop_score: gateDecision.stopScore });

// Log blocked submission event
db.audit.log({
kind: "task_failed",
message: `Task "${task.title}" submission blocked`,
taskId: task.id,
userId: (req as any).userId,
severity: "warn",
meta: { stopScore: gateDecision.stopScore, reasons: gateDecision.reasons },
});

return res.status(202).json({
id: task.id,
status: "BLOCKED",
Expand All @@ -124,6 +154,16 @@ export function createTaskRouter(db: Database, queue: QueueAdapter, gate: Enforc
// Work passed gate - mark as completed
db.updateTask(task.id, { status: "completed", stop_score: gateDecision.stopScore });

// Log task completed event
db.audit.log({
kind: "task_finished",
message: `Task "${task.title}" completed`,
taskId: task.id,
userId: (req as any).userId,
severity: "info",
meta: { stopScore: gateDecision.stopScore },
});

res.json({
id: task.id,
status: "completed",
Expand Down
4 changes: 4 additions & 0 deletions src/chat/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { costTracker } from "../billing/costTracker.ts";
import { selectModel } from "../billing/modelSelector.ts";
import { agentTools, executeTool } from "./tools.ts";
import { trackAICall, log, metrics } from "../monitoring/sentry.js";
import { events } from "../lib/events.js";
import Anthropic from "@anthropic-ai/sdk";
import OpenAI from "openai";
import { GoogleGenerativeAI } from "@google/generative-ai";
Expand Down Expand Up @@ -163,6 +164,9 @@ export class ChatManager {
}
}

// Log chat event for audit trail
events.chatSent(request.userId, request.agentName, request.message);

return {
chatId: chat.id,
messageId: assistantMessage.id,
Expand Down
Loading