168 lines
No EOL
4.9 KiB
TypeScript
168 lines
No EOL
4.9 KiB
TypeScript
import { Authentication } from "./Authentication";
|
|
|
|
// Log interface
|
|
interface LogData {
|
|
user_id: string;
|
|
type: string; // Standard types: "error", "update", "delete", "create", "login", "logout"
|
|
part: string; // The specific part/section being logged (can be multiple words, e.g., "profile settings", "resume upload")
|
|
message: string;
|
|
}
|
|
|
|
export class SendLog {
|
|
private auth: Authentication;
|
|
private static instance: SendLog;
|
|
private readonly COLLECTION_NAME = "logs"; // Make collection name a constant
|
|
|
|
private constructor() {
|
|
this.auth = Authentication.getInstance();
|
|
}
|
|
|
|
/**
|
|
* Get the singleton instance of SendLog
|
|
*/
|
|
public static getInstance(): SendLog {
|
|
if (!SendLog.instance) {
|
|
SendLog.instance = new SendLog();
|
|
}
|
|
return SendLog.instance;
|
|
}
|
|
|
|
/**
|
|
* Gets the current authenticated user's ID
|
|
* @returns The user ID or null if not authenticated
|
|
*/
|
|
private getCurrentUserId(): string | null {
|
|
const user = this.auth.getCurrentUser();
|
|
if (!user) {
|
|
console.debug("SendLog: No current user found");
|
|
return null;
|
|
}
|
|
console.debug("SendLog: Current user ID:", user.id);
|
|
return user.id;
|
|
}
|
|
|
|
/**
|
|
* Sends a log entry to PocketBase
|
|
* @param type The type of log entry
|
|
* @param part The specific part/section being logged
|
|
* @param message The log message
|
|
* @param overrideUserId Optional user ID to override the current user
|
|
* @returns Promise that resolves when the log is created
|
|
*/
|
|
public async send(type: string, part: string, message: string, overrideUserId?: string): Promise<void> {
|
|
try {
|
|
// Check authentication first
|
|
if (!this.auth.isAuthenticated()) {
|
|
console.error("SendLog: User not authenticated");
|
|
throw new Error("User must be authenticated to create logs");
|
|
}
|
|
|
|
// Get user ID
|
|
const userId = overrideUserId || this.getCurrentUserId();
|
|
if (!userId) {
|
|
console.error("SendLog: No user ID available");
|
|
throw new Error("No user ID available. User must be authenticated to create logs.");
|
|
}
|
|
|
|
// Prepare log data
|
|
const logData: LogData = {
|
|
user_id: userId,
|
|
type,
|
|
part,
|
|
message
|
|
};
|
|
|
|
console.debug("SendLog: Preparing to send log:", {
|
|
collection: this.COLLECTION_NAME,
|
|
data: logData,
|
|
authValid: this.auth.isAuthenticated(),
|
|
userId
|
|
});
|
|
|
|
// Get PocketBase instance
|
|
const pb = this.auth.getPocketBase();
|
|
|
|
// Create the log entry
|
|
await pb.collection(this.COLLECTION_NAME).create(logData);
|
|
|
|
console.debug("SendLog: Log created successfully");
|
|
} catch (error) {
|
|
// Enhanced error logging
|
|
if (error instanceof Error) {
|
|
console.error("SendLog: Failed to send log:", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
type,
|
|
part,
|
|
message
|
|
});
|
|
} else {
|
|
console.error("SendLog: Unknown error:", error);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get logs for a specific user
|
|
* @param userId The ID of the user to get logs for
|
|
* @param type Optional log type to filter by
|
|
* @param part Optional part/section to filter by
|
|
* @returns Array of log entries
|
|
*/
|
|
public async getUserLogs(userId: string, type?: string, part?: string): Promise<LogData[]> {
|
|
if (!this.auth.isAuthenticated()) {
|
|
throw new Error("User must be authenticated to retrieve logs");
|
|
}
|
|
|
|
try {
|
|
let filter = `user_id = "${userId}"`;
|
|
if (type) filter += ` && type = "${type}"`;
|
|
if (part) filter += ` && part = "${part}"`;
|
|
|
|
const result = await this.auth.getPocketBase().collection(this.COLLECTION_NAME).getFullList<LogData>({
|
|
filter,
|
|
sort: "-created"
|
|
});
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error("SendLog: Failed to get user logs:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get recent logs for the current user
|
|
* @param limit Maximum number of logs to retrieve
|
|
* @param type Optional log type to filter by
|
|
* @param part Optional part/section to filter by
|
|
* @returns Array of recent log entries
|
|
*/
|
|
public async getRecentLogs(limit: number = 10, type?: string, part?: string): Promise<LogData[]> {
|
|
if (!this.auth.isAuthenticated()) {
|
|
throw new Error("User must be authenticated to retrieve logs");
|
|
}
|
|
|
|
try {
|
|
const userId = this.getCurrentUserId();
|
|
if (!userId) {
|
|
throw new Error("No user ID available");
|
|
}
|
|
|
|
let filter = `user_id = "${userId}"`;
|
|
if (type) filter += ` && type = "${type}"`;
|
|
if (part) filter += ` && part = "${part}"`;
|
|
|
|
const result = await this.auth.getPocketBase().collection(this.COLLECTION_NAME).getList<LogData>(1, limit, {
|
|
filter,
|
|
sort: "-created"
|
|
});
|
|
|
|
return result.items;
|
|
} catch (error) {
|
|
console.error("SendLog: Failed to get recent logs:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|