Inject
TSXinject
1import {
2 ChangeLogService,
3 ContainerRegistryManager,
4 Inject,
5 Service,
6} from "@quan-erp/shared-backend-core";
7
8@Service()
9export class MyPluginService {
10 @Inject(ChangeLogService, ContainerRegistryManager.BUILTIN_PLUGIN)
11 private changeLogService: ChangeLogService;
12}Reference key
Every entry is scoped by three fields that form the feed for one record.
- pluginName — usually metadata.name (or builtin for core modules)
- referencePrefix — entity kind string (e.g. "SO", "currency", "project")
- referenceNumber — record id / code as string
Write methods
- addChangeLog(params: CreateServiceProps<ChangeLogDto>) — insert one entry; optional replyToId threads a reply; passive: true may notify the parent author
- addChangeLogs(params: CreateServiceProps<ChangeLogDto[]>) — bulk insert (same shape per item)
- ChangeLogDto — message (required), pluginName, referencePrefix, referenceNumber; optional createdBy, metadata, isCreatedBySystem, replyToId, passive
TSXaddChangeLog
1import {
2 ChangeLogService,
3 ContainerRegistryManager,
4 Inject,
5 Service,
6} from "@quan-erp/shared-backend-core";
7import metadata from "../../module.metadata.json" with { type: "json" };
8
9@Service()
10export class OrderChangeLogService {
11 @Inject(ChangeLogService, ContainerRegistryManager.BUILTIN_PLUGIN)
12 private changeLogService: ChangeLogService;
13
14 async onCreated(orderId: number, userId?: number) {
15 await this.changeLogService.addChangeLog({
16 data: {
17 pluginName: metadata.name,
18 referencePrefix: "SO",
19 referenceNumber: String(orderId),
20 message: `Sales order #${orderId} created.`,
21 isCreatedBySystem: !userId,
22 createdBy: userId,
23 metadata: { action: "create" },
24 },
25 });
26 }
27}Read method
- getChangeLogs({ pluginName, referencePrefix, referenceNumber, parentId?, skip, limit }) — paginated feed for that reference
- Omit parentId for root entries (replyTo IS NULL); pass parentId to list replies under one entry
- Each row includes reactions and replyCount
TSXgetChangeLogs
1import {
2 ChangeLogService,
3 ContainerRegistryManager,
4 Inject,
5 Service,
6} from "@quan-erp/shared-backend-core";
7import metadata from "../../module.metadata.json" with { type: "json" };
8
9@Service()
10export class OrderChangeLogService {
11 @Inject(ChangeLogService, ContainerRegistryManager.BUILTIN_PLUGIN)
12 private changeLogService: ChangeLogService;
13
14 async list(orderId: number) {
15 return this.changeLogService.getChangeLogs({
16 pluginName: metadata.name,
17 referencePrefix: "SO",
18 referenceNumber: String(orderId),
19 skip: 0,
20 limit: 20,
21 });
22 }
23}Reaction methods
- addReaction(params: CreateServiceProps<ChangeLogReactionDto>) — reaction + reactBy (user id) + changeLogId; notifies the entry author when not system-created
- removeReaction({ id, removeByUserId }) — remove the current user’s reaction for that change-log id
Frontend
Base frontend exposes ChangeLog UI and hooks (ChangeLog, useChangeLogQuery, useInfiniteChangeLog, reaction mutations). Prefer those on detail pages instead of building a custom feed.