89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import "server-only";
|
|
|
|
import { asc, eq } from "drizzle-orm";
|
|
|
|
import { getDb } from "@/db";
|
|
import {
|
|
outboxEvents,
|
|
catalogArtifacts,
|
|
catalogCharacters,
|
|
catalogWeapons,
|
|
glossaryAliases,
|
|
} from "@/db/schema";
|
|
import {
|
|
glossaryAliasInputSchema,
|
|
normalizeGlossaryAlias,
|
|
} from "@/lib/glossary";
|
|
import { writeAuditLog, type AuditActor } from "@/lib/audit-log";
|
|
|
|
const catalogTables = {
|
|
character: catalogCharacters,
|
|
weapon: catalogWeapons,
|
|
artifact: catalogArtifacts,
|
|
} as const;
|
|
|
|
export async function listGlossaryAliases() {
|
|
return getDb().select().from(glossaryAliases).orderBy(
|
|
asc(glossaryAliases.kind),
|
|
asc(glossaryAliases.alias),
|
|
);
|
|
}
|
|
|
|
export async function createGlossaryAlias(input: unknown, actor: AuditActor) {
|
|
const data = glossaryAliasInputSchema.parse(input);
|
|
const table = catalogTables[data.kind];
|
|
return getDb().transaction(async (tx) => {
|
|
const [item] = await tx
|
|
.select({ key: table.key })
|
|
.from(table)
|
|
.where(eq(table.key, data.catalogKey))
|
|
.limit(1);
|
|
if (!item) throw new Error("ไม่พบรายการใน Catalog");
|
|
const [created] = await tx.insert(glossaryAliases).values({
|
|
...data,
|
|
alias: data.alias.trim(),
|
|
normalizedAlias: normalizeGlossaryAlias(data.alias),
|
|
}).returning();
|
|
await writeAuditLog(tx, actor, {
|
|
action: "glossary_alias.created",
|
|
targetType: "glossary_alias",
|
|
targetId: created.id,
|
|
metadata: {
|
|
alias: created.alias,
|
|
kind: created.kind,
|
|
catalogKey: created.catalogKey,
|
|
},
|
|
});
|
|
await tx.insert(outboxEvents).values({
|
|
topic: "admin", aggregateId: created.id, eventType: "glossary.updated",
|
|
payload: { id: created.id, version: Date.now() },
|
|
});
|
|
return created;
|
|
});
|
|
}
|
|
|
|
export async function deleteGlossaryAlias(id: string, actor: AuditActor) {
|
|
return getDb().transaction(async (tx) => {
|
|
const [deleted] = await tx
|
|
.delete(glossaryAliases)
|
|
.where(eq(glossaryAliases.id, id))
|
|
.returning();
|
|
if (!deleted) throw new Error("ไม่พบ Shortcut");
|
|
await writeAuditLog(tx, actor, {
|
|
action: "glossary_alias.deleted",
|
|
targetType: "glossary_alias",
|
|
targetId: deleted.id,
|
|
metadata: {
|
|
alias: deleted.alias,
|
|
kind: deleted.kind,
|
|
catalogKey: deleted.catalogKey,
|
|
},
|
|
});
|
|
await tx.insert(outboxEvents).values({
|
|
topic: "admin", aggregateId: deleted.id, eventType: "glossary.updated",
|
|
payload: { id: deleted.id, version: Date.now() },
|
|
});
|
|
return deleted;
|
|
});
|
|
}
|