Tovább a tartalomhoz

Aktivitás napló

Az aktivitás napló funkció naplózza a felhasználói és rendszerszintű műveleteket. A bejegyzések a platform.activity_logs adatbázis táblában tárolódnak, és a Napló alkalmazásban tekinthetők meg.

import { activityLogService } from '$lib/server/activity-log/service';
// Minimális hívás
await activityLogService.log({ actionKey: 'user.login' });
// Teljes hívás
await activityLogService.log({
actionKey: 'plugin.installed',
userId: String(locals.user.id),
resourceType: 'plugin',
resourceId: pluginId,
context: { name: 'my-plugin', version: '1.0.0' }
});

A log() metódus fire-and-forget: nem dob kivételt, nem blokkolja az üzleti logikát. Hiba esetén csak console.error-t ír.

# Aktivitás napló be/kikapcsolása (alapértelmezett: true)
ACTIVITY_LOG_ENABLED=true

Ha false, az összes activityLogService.log() hívás azonnal visszatér, semmi sem kerül az adatbázisba.

apps/web/src/
├── lib/server/activity-log/
│ ├── service.ts # ActivityLogService + singleton
│ ├── repository.ts # ActivityLogRepository (findMany, count, insert)
│ ├── types.ts # ActivityEntry, ActivityLogInput, ActivityLogFilters
│ └── interpolate.ts # {{kulcs}} → érték helyettesítés
└── apps/log/
├── activity-logs.remote.ts # fetchActivityLogs szerver akció
└── components/
├── ActivityLog.svelte # Táblázatos megjelenítő komponens
└── activityLogColumns.ts # Oszlopdefiníciók

Az actionKey egy fordítási kulcs, amelyet a platform.translations táblában az activity névtérben kell tárolni.

{erőforrás}.{művelet}
actionKeyLeírás
user.loginFelhasználó bejelentkezett
user.logoutFelhasználó kijelentkezett
user.profile.updatedProfil frissítve
user.activatedFelhasználó aktiválva
user.deactivatedFelhasználó deaktiválva
user.group.addedFelhasználó csoporthoz adva
user.group.removedFelhasználó csoportból eltávolítva
user.role.assignedSzerepkör hozzárendelve
user.role.removedSzerepkör eltávolítva
role.createdSzerepkör létrehozva
role.deletedSzerepkör törölve
role.permission.addedJogosultság hozzáadva szerepkörhöz
role.permission.removedJogosultság eltávolítva szerepkörtől
plugin.installedPlugin telepítve
plugin.uninstalledPlugin eltávolítva

A fordításokat a platform.translations táblába kell felvenni az activity névtérben:

INSERT INTO platform.translations (namespace, key, locale, value) VALUES
('activity', 'user.login', 'hu', 'Bejelentkezés'),
('activity', 'user.login', 'en', 'Login'),
('activity', 'plugin.installed', 'hu', '{{name}} plugin telepítve'),
('activity', 'plugin.installed', 'en', 'Plugin {{name}} installed');

Ha nincs fordítás, az actionKey értéke jelenik meg tartalékként (pl. user.login).

A seed fájl: packages/database/src/seeds/sql/platform/translations_activity.sql

A context mező opcionális JSON objektum, amelynek értékei behelyettesíthetők a fordítási sablonba {{kulcs}} szintaxissal.

activityLogService.log({
actionKey: 'plugin.installed',
context: { name: 'chat-plugin', version: '2.1.0' }
});

Fordítási sablon: "{{name}} plugin telepítve (v{{version}})" Eredmény: "chat-plugin plugin telepítve (v2.1.0)"

MezőTípusKötelezőLeírás
iduuidigenAuto-generált egyedi azonosító
action_keyvarchar(255)igenFordítási kulcs (pl. user.login)
user_idvarchar(255)nemÉrintett felhasználó azonosítója
resource_typevarchar(100)nemErőforrás típusa (pl. plugin, user)
resource_idvarchar(255)nemErőforrás azonosítója
contextjsonbnemInterpolációs paraméterek
created_attimestamptzigenAuto-generált időbélyeg
interface ActivityLogInput {
actionKey: string;
userId?: string;
resourceType?: string;
resourceId?: string;
context?: Record<string, unknown>;
}
interface ActivityEntry {
id: string;
actionKey: string;
translatedAction?: string; // Lekérdezéskor töltődik ki
userId?: string;
resourceType?: string;
resourceId?: string;
context?: Record<string, unknown>;
createdAt: string; // ISO 8601
}
  1. Importáld a service-t:
import { activityLogService } from '$lib/server/activity-log/service';
  1. Hívd meg a sikeres művelet után:
export const myCommand = command(schema, async (input) => {
const result = await doSomething(input);
if (result.success) {
activityLogService.log({
actionKey: 'resource.action',
userId: String(locals.user.id),
resourceType: 'resource',
resourceId: String(result.id),
context: { /* opcionális adatok */ }
});
}
return result;
});
import { fetchActivityLogs } from '$apps/log/activity-logs.remote';
const result = await fetchActivityLogs({
page: 1,
pageSize: 20,
userId: '123', // opcionális szűrő
actionKey: 'user.login', // opcionális szűrő
sortBy: 'createdAt',
sortOrder: 'desc'
});
if (result.success) {
console.log(result.data); // ActivityEntry[]
console.log(result.pagination); // { page, pageSize, totalCount, totalPages }
}

Jogosultság: log.activity.view szükséges.

import { activityLogRepository } from '$lib/server/activity-log/repository';
// Bejegyzések lekérése
const entries = await activityLogRepository.findMany(
{ userId: '123', limit: 20, offset: 0 },
'hu' // locale a fordításhoz
);
// Darabszám
const count = await activityLogRepository.count({ userId: '123' });
// Mentés
await activityLogRepository.insert({
actionKey: 'user.login',
userId: '123'
});
FájlAction keyEsemény
apps/users/users.remote.tsuser.group.addedFelhasználó csoporthoz adva
apps/users/users.remote.tsuser.group.removedFelhasználó csoportból eltávolítva
apps/users/users.remote.tsuser.role.assignedSzerepkör hozzárendelve
apps/users/users.remote.tsuser.role.removedSzerepkör eltávolítva
apps/users/users.remote.tsuser.activatedFelhasználó aktiválva
apps/users/users.remote.tsuser.deactivatedFelhasználó deaktiválva
apps/settings/profile.remote.tsuser.profile.updatedProfil frissítve
apps/plugin-manager/plugins.remote.tsplugin.uninstalledPlugin eltávolítva
routes/api/plugins/upload/+server.tsplugin.installedPlugin telepítve
apps/users/roles.remote.tsrole.createdSzerepkör létrehozva
apps/users/roles.remote.tsrole.deletedSzerepkör törölve
apps/users/roles.remote.tsrole.permission.addedJogosultság hozzáadva
apps/users/roles.remote.tsrole.permission.removedJogosultság eltávolítva
Terminál
# Futtatás az apps/web könyvtárból
bun test src/lib/server/activity-log