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
+60
View File
@@ -0,0 +1,60 @@
import { implement } from "@conusai-kit/core"
import * as c from "../contract/index.js"
import { operationKey, recordBalanced, transition } from "../core/index.js"
import { ledgerServiceOf } from "./service.js"
export const LEDGER_PROCEDURES = [
implement(c.accounts, ({ ctx, input }) => ledgerServiceOf(ctx.container, ctx.kind).accounts(input.after)),
implement(c.account, ({ ctx, input }) => ledgerServiceOf(ctx.container, ctx.kind).account(input.accountId)),
implement(c.balances, ({ ctx, input }) =>
ledgerServiceOf(ctx.container, ctx.kind).balances(input.accountId, input.after),
),
implement(c.entries, ({ ctx, input }) =>
ledgerServiceOf(ctx.container, ctx.kind).entries(input.accountId, input.after),
),
implement(c.transactions, ({ ctx, input }) => ledgerServiceOf(ctx.container, ctx.kind).transactions(input.after)),
implement(c.transaction, ({ ctx, input }) =>
ledgerServiceOf(ctx.container, ctx.kind).transaction(input.transactionId),
),
implement(c.verify, ({ ctx }) => ledgerServiceOf(ctx.container, ctx.kind).verify()),
implement(c.createAccount, ({ ctx, input }) =>
ledgerServiceOf(ctx.container, "effect").createAccount(input, operationKey("account", input.requestId)),
),
implement(c.updateAccount, ({ ctx, input }) =>
ledgerServiceOf(ctx.container, "effect").updateAccount(
input.accountId,
input,
input.expectedVersion,
operationKey("account-update", input.requestId),
),
),
implement(c.record, ({ ctx, input }) =>
recordBalanced(ledgerServiceOf(ctx.container, "effect"), input.terms, input.requestId),
),
implement(c.post, ({ ctx, input }) =>
transition(
ledgerServiceOf(ctx.container, "effect"),
"post",
input.transactionId,
input.expectedVersion,
input.requestId,
),
),
implement(c.voidTransaction, ({ ctx, input }) =>
transition(
ledgerServiceOf(ctx.container, "effect"),
"void",
input.transactionId,
input.expectedVersion,
input.requestId,
),
),
implement(c.reverse, ({ ctx, input }) =>
transition(
ledgerServiceOf(ctx.container, "effect"),
"reverse",
input.transactionId,
input.expectedVersion,
input.requestId,
),
),
]
+203
View File
@@ -0,0 +1,203 @@
import {
businessAppError,
type RequestBusinessBinding,
requestBusinessBinding,
toBusinessError,
} from "@conusai-kit/business"
import type { Container, ProcedureKind } from "@conusai-kit/core"
import {
type Account,
type Balance,
type Entry,
ledgerCreateAccount,
ledgerGetAccount,
ledgerGetBalances,
ledgerGetTransaction,
ledgerListAccounts,
ledgerListEntries,
ledgerListTransactions,
ledgerPostTransaction,
ledgerRecordTransaction,
ledgerReverseTransaction,
ledgerUpdateAccount,
ledgerVerify,
ledgerVoidTransaction,
type Transaction,
} from "@conusai-sdk/ledger"
import { createClient } from "@conusai-sdk/ledger/client"
import { accountView, balanceView, entryView, transactionView, verificationView } from "../contract/index.js"
import { LEDGER_SERVICE, type LedgerReads, type LedgerService, type Page, readsOf } from "../core/ports.js"
async function answer<T>(
operation: Promise<{ data?: T; error?: unknown; response?: Response }>,
): Promise<Exclude<T, undefined>> {
let result: Awaited<typeof operation>
try {
result = await operation
} catch (error) {
throw businessAppError(toBusinessError(error, undefined))
}
if (result.error !== undefined || result.data === undefined)
throw businessAppError(toBusinessError(result.error, result.response))
return result.data as Exclude<T, undefined>
}
const account = (row: Account) =>
accountView.parse({
accountId: row.id,
code: row.code,
name: row.name,
currency: row.currency,
type: row.type,
normalBalance: row.normal_balance,
allowNegative: row.allow_negative,
status: row.status,
revision: row.revision.toString(),
})
const balance = (row: Balance) =>
balanceView.parse({
accountId: row.account_id,
currency: row.currency,
posted: row.posted.toString(),
pending: row.pending.toString(),
available: row.available.toString(),
})
const entry = (row: Entry) =>
entryView.parse({
entryId: row.id,
transactionId: row.transaction_id,
accountId: row.account_id,
currency: row.currency,
direction: row.direction,
amountMinor: row.amount_minor.toString(),
})
const transaction = (row: Transaction) =>
transactionView.parse({
transactionId: row.id,
revision: row.revision.toString(),
effectiveAt: row.effective_at,
description: row.description,
reference: row.reference ?? null,
reverses: row.reverses ?? null,
status: row.status,
entries: row.entries.map(entry),
})
const page = <A, B>(result: { data: A[]; next_after?: string | null }, view: (row: A) => B): Page<B> => ({
rows: result.data.map(view),
...(result.next_after ? { after: result.next_after } : {}),
})
const query = (after?: string) => ({ limit: 50, ...(after ? { after } : {}) })
export function sdkLedgerService(binding: RequestBusinessBinding): LedgerService {
const client = binding.client(createClient)
const org = { org_slug: binding.orgSlug }
return {
async accounts(after) {
return page(await answer(ledgerListAccounts({ client, path: org, query: query(after) })), account)
},
async account(id) {
return account(await answer(ledgerGetAccount({ client, path: { ...org, account_id: id } })))
},
async balances(id, after) {
return page(
await answer(
ledgerGetBalances({ client, path: org, query: { ...query(after), ...(id ? { account_id: id } : {}) } }),
),
balance,
)
},
async entries(id, after) {
return page(
await answer(ledgerListEntries({ client, path: { ...org, account_id: id }, query: query(after) })),
entry,
)
},
async transactions(after) {
return page(await answer(ledgerListTransactions({ client, path: org, query: query(after) })), transaction)
},
async transaction(id) {
return transaction(await answer(ledgerGetTransaction({ client, path: { ...org, transaction_id: id } })))
},
async verify() {
const result = await answer(ledgerVerify({ client, path: org }))
return verificationView.parse({ checkedAccounts: result.checked_accounts, drift: result.drift })
},
async createAccount(input, key) {
return account(
await answer(
ledgerCreateAccount({
client,
path: org,
body: {
code: input.code,
name: input.name,
currency: input.currency,
type: input.type,
normal_balance: input.normalBalance,
allow_negative: input.allowNegative,
idempotency_key: key,
},
}),
),
)
},
async updateAccount(id, input, revision, key) {
return account(
await answer(
ledgerUpdateAccount({
client,
path: { ...org, account_id: id },
body: {
name: input.name,
status: input.status,
allow_negative: input.allowNegative,
revision: BigInt(revision),
idempotency_key: key,
},
}),
),
)
},
async record(terms, key) {
return transaction(
await answer(
ledgerRecordTransaction({
client,
path: org,
body: {
effective_at: terms.effectiveAt,
description: terms.description,
reference: terms.reference ?? null,
status: terms.status,
entries: terms.entries.map((row) => ({
account_id: row.accountId,
direction: row.direction,
amount_minor: BigInt(row.amountMinor),
})),
idempotency_key: key,
},
}),
),
)
},
async transition(action, id, revision, key) {
const method =
action === "post" ? ledgerPostTransaction : action === "void" ? ledgerVoidTransaction : ledgerReverseTransaction
return transaction(
await answer(
method({
client,
path: { ...org, transaction_id: id },
body: { revision: BigInt(revision), idempotency_key: key },
}),
),
)
},
}
}
export function ledgerServiceOf(container: Container, kind: "effect"): LedgerService
export function ledgerServiceOf(container: Container, kind: ProcedureKind): LedgerReads
export function ledgerServiceOf(container: Container, kind: ProcedureKind): LedgerReads {
const service = container.has(LEDGER_SERVICE)
? container.resolve(LEDGER_SERVICE)
: sdkLedgerService(requestBusinessBinding(container))
return kind === "effect" ? service : readsOf(service)
}