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
21 changes: 10 additions & 11 deletions packages/platform-objects/scripts/i18n-extract.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,14 @@ import {
// bundles keep working until then.

// ── Audit ─────────────────────────────────────────────────────────────────
// sys_audit_log / sys_activity / sys_comment moved to @objectstack/plugin-audit
// and sys_presence to @objectstack/service-realtime (ADR-0029 K2 / D8). Their
// i18n extraction now lives in those packages; the already-generated bundles
// here keep working until the next regeneration. sys_attachment stays here
// pending the storage-domain decomposition (it belongs with service-storage).
import {
SysAuditLog,
SysPresence,
SysActivity,
SysComment,
SysAttachment,
SysNotification,
SysAttachment,
SysEmail,
SysEmailTemplate,
SysSavedReport,
Expand Down Expand Up @@ -144,13 +145,11 @@ export default defineStack({
// Security: RBAC moved to @objectstack/plugin-security, sharing to
// @objectstack/plugin-sharing (ADR-0029 K2 / D8).

// Audit
SysAuditLog,
SysPresence,
SysActivity,
SysComment,
SysAttachment,
// Audit (sys_audit_log / sys_activity / sys_comment moved to
// @objectstack/plugin-audit; sys_presence to @objectstack/service-realtime;
// sys_attachment stays pending storage-domain decomposition)
SysNotification,
SysAttachment,
SysEmail,
SysEmailTemplate,
SysSavedReport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ export const SETUP_NAV_CONTRIBUTIONS: NavigationContribution[] = [
group: 'group_diagnostics',
priority: BASE_PRIORITY,
items: [
// Audit Logs (sys_audit_log) is contributed by @objectstack/plugin-audit
// which now owns it (ADR-0029 K2).
{ id: 'nav_sessions', type: 'object', label: 'Sessions', objectName: 'sys_session', icon: 'monitor' },
{ id: 'nav_audit_logs', type: 'object', label: 'Audit Logs', objectName: 'sys_audit_log', icon: 'scroll-text' },
{ id: 'nav_notifications', type: 'object', label: 'Notification Events', objectName: 'sys_notification', viewName: 'recent', icon: 'bell', requiresObject: 'sys_notification' },
],
},
Expand Down
11 changes: 6 additions & 5 deletions packages/platform-objects/src/audit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
* platform-objects/audit — Audit & Realtime Platform Objects
*/

export { SysAuditLog } from './sys-audit-log.object.js';
export { SysPresence } from './sys-presence.object.js';
export { SysActivity } from './sys-activity.object.js';
export { SysComment } from './sys-comment.object.js';
export { SysAttachment } from './sys-attachment.object.js';
// sys_audit_log / sys_activity / sys_comment moved to @objectstack/plugin-audit
// and sys_presence to @objectstack/service-realtime (ADR-0029 K2).
// sys_notification stays here pending ADR-0030 messaging rework; sys_attachment
// stays here pending the storage-domain decomposition (it belongs with
// @objectstack/service-storage's sys_file, not the audit plugin).
export { SysNotification } from './sys-notification.object.js';
export { SysAttachment } from './sys-attachment.object.js';
export { SysEmail } from './sys-email.object.js';
export { SysEmailTemplate } from './sys-email-template.object.js';
export { SysSavedReport } from './sys-saved-report.object.js';
Expand Down
6 changes: 3 additions & 3 deletions packages/platform-objects/src/platform-objects.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import {
// RBAC objects (SysRole/SysPermissionSet/… + defaultPermissionSets) moved to
// @objectstack/plugin-security and the sharing objects to
// @objectstack/plugin-sharing per ADR-0029 K2 — see their packages' tests.
import { SysAuditLog, SysPresence } from './audit/index.js';
// sys_audit_log / sys_activity / sys_comment / sys_attachment moved to
// @objectstack/plugin-audit and sys_presence to @objectstack/service-realtime
// per ADR-0029 K2 — see their packages' tests.
// sys_webhook moved to @objectstack/plugin-webhooks per ADR-0029 (K2.a).
import {
SysMetadata,
Expand All @@ -42,8 +44,6 @@ const systemObjects = [
['SysApiKey', SysApiKey, 'sys_api_key'],
['SysTwoFactor', SysTwoFactor, 'sys_two_factor'],
['SysUserPreference', SysUserPreference, 'sys_user_preference'],
['SysAuditLog', SysAuditLog, 'sys_audit_log'],
['SysPresence', SysPresence, 'sys_presence'],
['SysMetadata', SysMetadata, 'sys_metadata'],
['SysMetadataHistoryObject', SysMetadataHistoryObject, 'sys_metadata_history'],
['SysSetting', SysSetting, 'sys_setting'],
Expand Down
33 changes: 33 additions & 0 deletions packages/plugins/plugin-audit/scripts/i18n-extract.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* Build-time only config for `os i18n extract` (ADR-0029 D8). Not deployed.
* The plugin owns the i18n extraction for the objects it owns; the
* `translations` baseline is this plugin's OWN generated bundles so re-running
* `--merge` preserves every hand-translated string. (Initial zh-CN/ja-JP/es-ES
* strings were seeded from @objectstack/platform-objects.)
*
* os i18n extract packages/plugins/plugin-audit/scripts/i18n-extract.config.ts \
* --locales=zh-CN,ja-JP,es-ES --fill=default --objects-only \
* --out=packages/plugins/plugin-audit/src/translations
*/

import { defineStack } from '@objectstack/spec';
import { SysAuditLog } from '../src/objects/sys-audit-log.object.js';
import { SysActivity } from '../src/objects/sys-activity.object.js';
import { SysComment } from '../src/objects/sys-comment.object.js';
import { enObjects } from '../src/translations/en.objects.generated.js';
import { zhCNObjects } from '../src/translations/zh-CN.objects.generated.js';
import { jaJPObjects } from '../src/translations/ja-JP.objects.generated.js';
import { esESObjects } from '../src/translations/es-ES.objects.generated.js';

export default defineStack({
name: 'plugin-audit-i18n-extract',
objects: [SysAuditLog, SysActivity, SysComment] as any,
translations: [
{ en: { objects: enObjects } },
{ 'zh-CN': { objects: zhCNObjects } },
{ 'ja-JP': { objects: jaJPObjects } },
{ 'es-ES': { objects: esESObjects } },
],
});
36 changes: 35 additions & 1 deletion packages/plugins/plugin-audit/src/audit-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

import type { Plugin, PluginContext } from '@objectstack/core';
import type { IDataEngine } from '@objectstack/spec/contracts';
import { SysAuditLog, SysActivity, SysComment, SysAttachment, SysNotification } from '@objectstack/platform-objects/audit';
import { SysAuditLog, SysActivity, SysComment } from './objects/index.js';
// Registered here but still owned by platform-objects (the plugin contributes
// them to the kernel without owning the definition yet):
// - sys_notification — reworked by ADR-0030 messaging (notification→event).
// - sys_attachment — a file↔record link belonging with service-storage's
// sys_file; moves in the storage-domain decomposition, not this audit move.
import { SysNotification, SysAttachment } from '@objectstack/platform-objects/audit';
import { installAuditWriters, type MessagingEmitSurface } from './audit-writers.js';

/**
Expand Down Expand Up @@ -32,8 +38,36 @@ export class AuditPlugin implements Plugin {
defaultDatasource: 'cloud',
namespace: 'sys',
objects: [SysAuditLog, SysActivity, SysComment, SysAttachment, SysNotification],
// ADR-0029 D7 — contribute the Audit Logs entry into the Setup app's
// `group_diagnostics` slot. The plugin owns sys_audit_log (K2).
navigationContributions: [
{
app: 'setup',
group: 'group_diagnostics',
priority: 100,
items: [
{ id: 'nav_audit_logs', type: 'object', label: 'Audit Logs', objectName: 'sys_audit_log', icon: 'scroll-text' },
],
},
],
});

// ADR-0029 D8 — contribute this plugin's object translations to the i18n
// service on kernel:ready (the i18n plugin may register after this one).
if (typeof (ctx as any).hook === 'function') {
(ctx as any).hook('kernel:ready', async () => {
try {
const i18n = ctx.getService<any>('i18n');
if (i18n && typeof i18n.loadTranslations === 'function') {
const { AuditTranslations } = await import('./translations/index.js');
for (const [locale, data] of Object.entries(AuditTranslations)) {
i18n.loadTranslations(locale, data as Record<string, unknown>);
}
}
} catch { /* i18n optional */ }
});
}

ctx.logger.info('Audit Plugin initialized');
}

Expand Down
18 changes: 18 additions & 0 deletions packages/plugins/plugin-audit/src/objects/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* Audit & collaboration objects owned by `@objectstack/plugin-audit`
* (ADR-0029 K2). Moved here from the `@objectstack/platform-objects` monolith
* so the plugin owns its data model + behavior — exactly the objects the audit
* writers produce/observe (sys_audit_log + sys_activity rows; sys_comment
* @mention hook).
*
* Intentionally NOT moved here:
* - `sys_notification` — reworked by ADR-0030 messaging.
* - `sys_attachment` — a file↔record link belonging with service-storage's
* sys_file; stays in platform-objects pending the storage-domain move.
*/

export { SysAuditLog } from './sys-audit-log.object.js';
export { SysActivity } from './sys-activity.object.js';
export { SysComment } from './sys-comment.object.js';
36 changes: 36 additions & 0 deletions packages/plugins/plugin-audit/src/objects/objects.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

import { describe, it, expect } from 'vitest';
import { StorageNameMapping } from '@objectstack/spec/system';
import { SysAuditLog, SysActivity, SysComment } from './index.js';

/**
* Canonical-identity coverage for the audit/collaboration objects this plugin
* owns after the ADR-0029 K2 move out of @objectstack/platform-objects. Locks
* in the short names, system flag, and the storage-name resolution so a future
* rename can't silently change the physical table.
*/
const ownedObjects = [
['SysAuditLog', SysAuditLog, 'sys_audit_log'],
['SysActivity', SysActivity, 'sys_activity'],
['SysComment', SysComment, 'sys_comment'],
] as const;

describe('@objectstack/plugin-audit objects', () => {
it.each(ownedObjects)('%s uses a canonical sys_ short name', (_name, object, name) => {
expect(object.name).toBe(name);
});

it.each(ownedObjects)('%s resolves to the same physical table name', (_name, object, name) => {
expect(StorageNameMapping.resolveTableName(object)).toBe(name);
});

it.each(ownedObjects)('%s is marked as a system object', (_name, object) => {
expect(object.isSystem).toBe(true);
});

it.each(ownedObjects)('%s does not carry deprecated storage identity fields', (_name, object) => {
expect((object as any).namespace).toBeUndefined();
expect((object as any).tableName).toBeUndefined();
});
});
Loading