ConusAI vendor v0.1.0-dev.20261027+9b1131fb
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-dev.20261027+9b1131fb
2026-10-27 18:05:17 +00:00
commit 3102273ec7
538 changed files with 80203 additions and 0 deletions
+165
View File
@@ -0,0 +1,165 @@
// What happens exactly once per change.
//
// The audit event and the usage fact hang off the outbox record the changing transaction wrote, and
// the relay delivers a record exactly once per subscriber, so a note created by a retried request
// is audited and metered once, and one whose process died before the relay ran still is, because
// the record committed with the row. The platform's audit and usage APIs are HTTP and cannot join
// the transaction: each call carries a key derived from the record, so a delivery the relay repeats
// after a crash is the same event to the platform and not a second one.
//
// Ids, counts and versions only: no title and no body in an audit event (spec §9.4).
import { type EventContext, internal } from "@conusai-kit/core"
import { DATA_SOURCE } from "@conusai-kit/data"
import { auditEventId, FILES_AUDIT, FILES_SCOPE, FILES_USAGE } from "@conusai-kit/files"
import {
ATTACHMENT_ADDED,
ATTACHMENT_REMOVED,
attachments,
NOTE_CREATED,
NOTE_DELETED,
NOTE_UPDATED,
NOTES_CREATED_METER,
} from "../contract/index.js"
interface InProject {
orgId: string
workspaceId: string
projectId: string
}
/**
* The organization a delivery belongs to comes from the container -- the scope the relay rebuilt
* from the outbox record's own `orgId` -- and is compared with the payload's: a record that named
* another tenant is refused here rather than written there.
*/
function assertSameOrg(ctx: EventContext, payload: InProject): void {
const ambient = ctx.container.resolve(FILES_SCOPE)
if (ambient.orgId !== payload.orgId) {
throw internal(`a notes event of organization ${payload.orgId} was delivered in ${ambient.orgId}`)
}
}
interface AuditShape<P extends InProject> {
action: string
actor: (payload: P) => string
target: (payload: P) => { id: string; type: string }
/** What makes two events of one action on one target two events: a version, a link's id. */
occurrence: (payload: P) => string
data: (payload: P) => Record<string, unknown>
}
/** A subscriber that writes one audit event per record. */
export function auditing<P extends InProject>(shape: AuditShape<P>) {
return async (event: { name: string; payload: P }, ctx: EventContext): Promise<void> => {
const { payload } = event
assertSameOrg(ctx, payload)
await ctx.container.resolve(FILES_AUDIT).log(shape.action, {
actor: { kind: "human", id: shape.actor(payload) },
target: shape.target(payload),
event_id: await auditEventId(shape.action, shape.occurrence(payload)),
data: { ...shape.data(payload), projectId: payload.projectId },
})
}
}
type Payloads = {
created: InProject & { noteId: string; createdBy: string }
updated: InProject & { noteId: string; version: number; updatedBy: string }
deleted: InProject & { noteId: string; deletedBy: string; attachmentCount: number }
added: InProject & { noteId: string; attachmentId: string; fileId: string; attachedBy: string }
removed: InProject & { noteId: string; attachmentId: string; fileId: string; removedBy: string }
}
// The organization has to be in the target or the in-app viewer could not show one
// organization's events without another's (apps/web/src/server/audit.ts): a resource target is
// `<org id>/<resource id>` here, the id being what an outbox payload carries; the transport
// writes the same rule with the slug it has, and the viewer matches either.
const note = (payload: InProject & { noteId: string }) => ({ id: `${payload.orgId}/${payload.noteId}`, type: "note" })
const auditCreated = auditing<Payloads["created"]>({
action: NOTE_CREATED,
actor: (p) => p.createdBy,
target: note,
occurrence: (p) => p.noteId,
data: () => ({}),
})
const auditUpdated = auditing<Payloads["updated"]>({
action: NOTE_UPDATED,
actor: (p) => p.updatedBy,
target: note,
occurrence: (p) => `${p.noteId}:${p.version}`,
data: (p) => ({ version: p.version }),
})
const auditDeleted = auditing<Payloads["deleted"]>({
action: NOTE_DELETED,
actor: (p) => p.deletedBy,
target: note,
occurrence: (p) => p.noteId,
data: (p) => ({ attachmentCount: p.attachmentCount }),
})
const auditAdded = auditing<Payloads["added"]>({
action: ATTACHMENT_ADDED,
actor: (p) => p.attachedBy,
target: note,
occurrence: (p) => p.attachmentId,
data: (p) => ({ attachmentId: p.attachmentId, fileId: p.fileId }),
})
const auditRemoved = auditing<Payloads["removed"]>({
action: ATTACHMENT_REMOVED,
actor: (p) => p.removedBy,
target: note,
occurrence: (p) => p.attachmentId,
data: (p) => ({ attachmentId: p.attachmentId, fileId: p.fileId }),
})
/** One audit event and one usage fact per note created. */
export async function onNoteCreated(event: { name: string; payload: Payloads["created"] }, ctx: EventContext) {
await auditCreated(event, ctx)
const usage = ctx.container.resolve(FILES_USAGE)
await usage.track({
customer: { externalId: event.payload.orgId },
meter: NOTES_CREATED_METER,
quantity: 1,
idempotencyKey: `${NOTES_CREATED_METER}.${event.payload.noteId}`,
})
// Awaited: a sink that sends per call is then durable before the relay marks the record published.
await usage.flush()
}
export const onNoteUpdated = auditUpdated
export const onNoteDeleted = auditDeleted
export const onAttachmentAdded = auditAdded
export const onAttachmentRemoved = auditRemoved
/**
* A file that stopped being stored takes its links with it, so a note never lists an attachment
* nobody can open. The scope is the delivery's own organization and a system actor with the two
* deeper ids of the record the files module wrote in that organization's transaction.
*/
export async function onFileDeleted(
event: { name: string; payload: InProject & { fileId: string } },
ctx: EventContext,
): Promise<void> {
const { payload } = event
assertSameOrg(ctx, payload)
const ambient = ctx.container.resolve(FILES_SCOPE)
const scope = {
level: "project" as const,
actor: ambient.actor,
orgId: ambient.orgId,
workspaceId: payload.workspaceId,
projectId: payload.projectId,
}
await ctx.container.resolve(DATA_SOURCE).unitOfWork.run(scope, async (tx) => {
for (;;) {
const page = await tx.of(attachments).list({ where: [{ field: "fileId", op: "eq", value: payload.fileId }] })
for (const link of page.items) await tx.of(attachments).delete(link.id)
if (!page.hasMore) break
}
})
}