ConusAI vendor v0.1.0-beta.114
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-beta.114
2026-11-14 09:56:45 +00:00
commit 1ce8d23c35
867 changed files with 122104 additions and 0 deletions
+128
View File
@@ -0,0 +1,128 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// Simulated ports prove module boundaries, not live service/database acceptance.
import { actorRef, projectRef } from "@conusai-kit/business"
import type { ProjectScope } from "@conusai-kit/core"
import { describe, expect, it, vi } from "vitest"
import type { ActivitiesService, TaskRecord } from "../core/ports.js"
import { addComment, changeTask, createTask, listComments, listTasks, ownedTask, updateTask } from "../core/tasks.js"
import { en } from "../i18n/en.js"
import { lt } from "../i18n/lt.js"
const bindingId = "01900000-0000-7000-8000-000000000001"
const projectId = "01900000-0000-7000-8000-000000000002"
const taskId = "act_01900000-0000-7000-8000-000000000003"
const userId = "01900000-0000-7000-8000-000000000004"
const requestId = "01900000-0000-7000-8000-000000000005"
const scope: ProjectScope = {
level: "project",
orgId: bindingId,
workspaceId: bindingId,
projectId,
actor: { userId: userId as never },
}
function fixture() {
const task: TaskRecord = {
taskId,
subject: "Synthetic task",
body: "Fixture details",
revision: "1",
status: "open",
targets: [projectRef(bindingId, projectId)],
createdAt: "2026-11-03T00:00:00Z",
}
const outcomes = new Map<string, { taskId: string; revision: string }>()
let commits = 0
const service: ActivitiesService = {
bindingId,
get: vi.fn(async () => ({ ...task })),
list: vi.fn(async () => ({ rows: [{ ...task }] })),
comments: vi.fn(async () => ({ rows: [] })),
timeline: vi.fn(async () => ({ rows: [{ ...task }] })),
create: vi.fn(async () => ({ taskId, revision: "1" })),
update: vi.fn(async () => ({ taskId, revision: "2" })),
comment: vi.fn(async () => ({
commentId: "cmt_01900000-0000-7000-8000-000000000003",
revision: "2",
})),
change: vi.fn(async (input) => {
const prior = outcomes.get(input.key)
if (prior) return prior
if (input.expectedVersion !== task.revision) throw new Error("fixture stale revision")
task.status = input.state === "done" ? "done" : "open"
task.revision = (BigInt(task.revision) + 1n).toString()
const result = { taskId, revision: task.revision }
outcomes.set(input.key, result)
commits += 1
return result
}),
}
return { task, service, commits: () => commits }
}
describe("project Activities module boundaries (simulated ports)", () => {
it("derives project and participant references from resolved scope, with an operation key", async () => {
const { service } = fixture()
await createTask(service, scope, { subject: " Task ", requestId })
expect(service.create).toHaveBeenCalledWith({
subject: "Task",
body: "",
target: projectRef(bindingId, projectId),
participant: actorRef(bindingId, userId),
key: `activities:${projectId}:create:${requestId}`,
})
await listTasks(service, scope, {})
expect(service.list).toHaveBeenCalledWith({ target: projectRef(bindingId, projectId), status: "open" })
})
it("refuses guessed task ids from another app project before writes or discussion reads", async () => {
const { task, service } = fixture()
task.targets = [projectRef(bindingId, "01900000-0000-7000-8000-000000000099")]
for (const operation of [
() => ownedTask(service, scope, taskId),
() => listComments(service, scope, { taskId }),
() => addComment(service, scope, { taskId, body: "Synthetic", expectedVersion: "1", requestId }),
() => changeTask(service, scope, { taskId, expectedVersion: "1", requestId }, "done"),
])
await expect(operation()).rejects.toMatchObject({ code: "not_found" })
expect(service.comment).not.toHaveBeenCalled()
expect(service.change).not.toHaveBeenCalled()
expect(service.comments).not.toHaveBeenCalled()
})
it("refuses future revision prediction before external mutation", async () => {
const { service } = fixture()
await expect(changeTask(service, scope, { taskId, expectedVersion: "2", requestId }, "done")).rejects.toMatchObject(
{ code: "conflict" },
)
expect(service.change).not.toHaveBeenCalled()
})
it("lets the service deduplicate a lost-response retry without a second domain commit", async () => {
const f = fixture()
const input = { taskId, expectedVersion: "1", requestId }
const first = await changeTask(f.service, scope, input, "done")
expect(await changeTask(f.service, scope, input, "done")).toEqual(first)
expect(f.commits()).toBe(1)
expect(await changeTask(f.service, scope, { ...input, expectedVersion: "2" }, "open")).toEqual({
taskId,
revision: "3",
})
expect(f.commits()).toBe(2)
})
it("rechecks project ownership after discussion reads", async () => {
const { service } = fixture()
vi.mocked(service.comments).mockImplementation(async () => {
vi.mocked(service.get).mockResolvedValue({
...fixture().task,
targets: [projectRef(bindingId, "01900000-0000-7000-8000-000000000099")],
})
return { rows: [{ commentId: taskId, body: "Must not be returned", author: null, erased: false }] }
})
await expect(listComments(service, scope, { taskId })).rejects.toMatchObject({ code: "not_found" })
})
it("passes the authorized target to an update so the adapter preserves other fields", async () => {
const { service } = fixture()
await updateTask(service, scope, { taskId, subject: "Changed", body: "Details", expectedVersion: "1", requestId })
expect(service.update).toHaveBeenCalledWith(
expect.objectContaining({ target: projectRef(bindingId, projectId), expectedVersion: "1", subject: "Changed" }),
)
})
it("has the same translated keys in both languages", () =>
expect(Object.keys(en).sort()).toEqual(Object.keys(lt).sort()))
})
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
import { businessAppError, toBusinessError } from "@conusai-kit/business"
import { businessRefusalNotices } from "@conusai-kit/business/refusals"
import { describe, expect, it } from "vitest"
import { en } from "../i18n/en.js"
import { lt } from "../i18n/lt.js"
import { describeFailure, type Labels } from "../ui/labels.js"
// What the loader hands the forms (ui/pages.tsx): the module's messages and the kit's refusal sentences.
const labelsOf = (messages: typeof en, locale: "en" | "lt"): Labels => ({
...messages,
refusals: businessRefusalNotices(locale, {
conflict: messages.conflict,
revision_conflict: messages.conflict,
invalid: messages.invalid,
}),
})
describe("Activities error text", () => {
it.each([
[en, "en"],
[lt, "lt"],
] as const)("translates known refusals without showing remote detail", (messages, locale) => {
const labels = labelsOf(messages, locale)
for (const [code, expected] of [
["business_conflict", messages.conflict],
["business_revision_conflict", messages.conflict],
["business_invalid", messages.invalid],
["service_partition_revoked", labels.refusals.service_partition_revoked],
["service_degraded", labels.refusals.service_degraded],
["service_migrating", labels.refusals.service_migrating],
]) {
const message = describeFailure({ problem: { code, detail: "upstream private fixture value" } }, labels)
expect(message).toBe(expected)
expect(message).not.toContain("private fixture value")
}
expect(describeFailure({ problem: { code: "untrusted", detail: "upstream private fixture value" } }, labels)).toBe(
messages.unavailable,
)
})
it("tells a Lithuanian reader the kit's sentence for a refusal of the Activities service", () => {
const refusal = businessAppError(
toBusinessError(
{ type: "urn:conusai:activities:erased-participant", detail: "upstream private fixture value" },
new Response(null, { status: 409 }),
),
)
expect(describeFailure(refusal, labelsOf(lt, "lt"))).toBe(
"Dalyvio duomenys ištrinti, todėl šios veiklos pakeisti negalima.",
)
expect(describeFailure({ problem: { code: "service_migrating" } }, labelsOf(lt, "lt"))).toBe(
"Paslauga atnaujinama. Bandykite po kelių minučių.",
)
})
})
+27
View File
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
import type { TransportCaller } from "@conusai-kit/core"
import type { IsolationFixture, IsolationTenant } from "@conusai-kit/testing"
import { businessModulesOn } from "../../index.js"
const id = "01900000-0000-7000-8000-000000000001"
const slugs = (t: IsolationTenant) => ({ org: t.orgSlug, workspace: t.workspaceSlug, project: t.projectSlug })
const task = (t: IsolationTenant) => ({ ...slugs(t), taskId: `act_${id}` })
const mutate = (t: IsolationTenant) => ({ ...task(t), expectedVersion: "1", requestId: id })
export const activitiesIsolationFixtures: Record<string, IsolationFixture> = {
"activities.task.list": { input: slugs },
"activities.task.get": { input: task },
"activities.timeline.list": { input: slugs },
"activities.task.create": { input: (t) => ({ ...slugs(t), subject: "Synthetic", requestId: id }) },
"activities.task.update": { input: (t) => ({ ...mutate(t), subject: "Synthetic", body: "Fixture" }) },
"activities.task.complete": { input: mutate },
"activities.task.reopen": { input: mutate },
"activities.comment.list": { input: task },
"activities.comment.add": { input: (t) => ({ ...mutate(t), body: "Synthetic" }) },
}
export const isolation: {
seed(
call: TransportCaller,
inProject: { org: string; workspace: string; project: string },
): Promise<Record<string, string>>
fixtures: Record<string, IsolationFixture>
} = { seed: async () => ({}), fixtures: businessModulesOn.includes("activities") ? activitiesIsolationFixtures : {} }
@@ -0,0 +1,163 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// Generated SDK + synthetic HTTP proves wire contracts, never live service acceptance.
import { actorRef, projectRef, requestBusinessBinding } from "@conusai-kit/business"
import { businessServiceHooks } from "@conusai-kit/business/server"
import { Container, type ServiceAdmissionContext } from "@conusai-kit/core"
import { afterEach, describe, expect, it, vi } from "vitest"
import { sdkActivitiesService } from "../adapters/service.js"
import { activityId, commentReceipt, receipt } from "../contract/index.js"
import { activitiesModule } from "../module.js"
const bindingId = "01900000-0000-7000-8000-000000000001"
const projectId = "01900000-0000-7000-8000-000000000002"
const actorId = "01900000-0000-7000-8000-000000000003"
const taskId = "act_01900000-0000-7000-8000-000000000004"
const commentId = "cmt_01900000-0000-7000-8000-000000000005"
const revision = "9007199254740993"
const target = projectRef(bindingId, projectId)
const member = actorRef(bindingId, actorId)
const task = {
id: taskId,
kind: "task",
status: "open",
revision: "RAW_REVISION",
subject: "Synthetic task",
body: "Details",
targets: [target],
participants: [member],
assignee: member,
due_at: "2026-12-01T00:00:00Z",
ext: { fixture: "preserve" },
pinned: true,
created_at: "2026-11-03T00:00:00Z",
updated_at: "2026-11-03T00:00:00Z",
erased: false,
deleted: false,
}
function json(value: unknown) {
return new Response(JSON.stringify(value).replaceAll('"RAW_REVISION"', revision), {
headers: { "content-type": "application/json" },
})
}
async function fixture(reply: (request: Request) => Promise<Response> | Response) {
const requests: Request[] = []
vi.stubGlobal("fetch", async (input: Request | string | URL) => {
const request = new Request(input)
requests.push(request.clone())
return reply(request)
})
const container = new Container()
const hooks = businessServiceHooks({
env: { apiUrl: "https://platform.example.test/api", token: "synthetic-token", orgSlug: "fixture" },
platformOrganizationId: 7,
platformProjectId: 9,
platformEnvironmentId: 11,
profile: "postgres",
controlPlane: {
lookup: async (appTenantId) => ({
partition_major: 1,
binding_id: bindingId,
organization_id: 7,
project_id: 9,
environment_id: 11,
environment_uuid: projectId,
app_tenant_id: appTenantId,
}),
observe: async () => {
throw new Error("This fixture does not certify readiness")
},
},
})
const context: ServiceAdmissionContext = {
container,
module: "activities",
procedure: "activities.task.list",
kind: "read",
scope: { level: "org", orgId: bindingId, actor: { userId: actorId } },
}
await hooks.prepareServices?.(container, context, activitiesModule.serviceRequirements ?? [])
return { service: sdkActivitiesService(requestBusinessBinding(container)), requests }
}
afterEach(() => vi.unstubAllGlobals())
describe("Activities generated wire adapter (synthetic HTTP)", () => {
it("accepts real resource prefixes and preserves int64 revision digits", async () => {
const { service, requests } = await fixture(() => json(task))
const result = await service.get(taskId)
expect(result.revision).toBe(revision)
expect(activityId.parse(result.taskId)).toBe(taskId)
expect(() => activityId.parse(taskId.slice(4))).toThrow()
expect(requests[0]?.headers.get("Conusai-App-Binding")).toBe(bindingId)
expect(requests[0]?.headers.get("Conusai-App-Actor")).toBe(actorId)
expect(requests[0]?.redirect).toBe("error")
})
it("forwards a service cursor unchanged in both directions", async () => {
const cursor = "eyJvcmRlciI6WzEsInN5bnRoZXRpYyJdfQ"
const { service, requests } = await fixture(() => json({ data: [task], next_after: cursor }))
expect((await service.list({ target, after: cursor })).after).toBe(cursor)
expect(new URL(requests[0]?.url ?? "").searchParams.get("after")).toBe(cursor)
expect(new URL(requests[0]?.url ?? "").searchParams.get("target")).toBe(target)
})
it("preserves untouched fields on edit and sends revision digits exactly", async () => {
let body = ""
const { service } = await fixture(async (request) => {
if (request.method === "GET") return json(task)
body = await request.text()
return json({ id: taskId, revision: "RAW_REVISION" })
})
const current = await service.get(taskId)
const result = await service.update({
task: current,
target,
subject: "Changed",
body: "Edited",
expectedVersion: revision,
key: "synthetic-update",
})
expect(receipt.parse(result).revision).toBe(revision)
expect(body).toContain(`"revision":${revision}`)
expect(JSON.parse(body).fields).toMatchObject({
assignee: member,
due_at: task.due_at,
ext: task.ext,
participants: [member],
targets: [target],
pinned: true,
subject: "Changed",
body: "Edited",
})
})
it("returns the actual comment receipt instead of inventing a comment body", async () => {
const { service } = await fixture(() => json({ id: commentId, revision: "RAW_REVISION" }))
const result = await service.comment({
taskId,
body: "Synthetic comment",
expectedVersion: revision,
key: "synthetic-comment",
})
expect(commentReceipt.parse(result)).toEqual({ commentId, revision })
expect(result).not.toHaveProperty("body")
})
it("refuses a changed project target before the adapter writes", async () => {
const other = projectRef(bindingId, "01900000-0000-7000-8000-000000000099")
const { service, requests } = await fixture(() => json({ ...task, targets: [other] }))
await expect(
service.update({
task: {
taskId,
subject: "Old",
body: "",
revision,
status: "open",
targets: [target],
createdAt: task.created_at,
},
target,
subject: "Changed",
body: "Edited",
expectedVersion: revision,
key: "synthetic-foreign",
}),
).rejects.toMatchObject({ code: "not_found" })
expect(requests.every((request) => request.method === "GET")).toBe(true)
})
})