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
+132
View File
@@ -0,0 +1,132 @@
// The procedure contracts of the catalog module: schemas and names, no handler and no port.
//
// The module is a client of the platform's Catalog service (B-wave contract §3.14): products and their
// imports live there, in the deployment's organization, and every procedure is one service call. A read
// reads; an import is an `effect` (it calls an external service and writes nothing of this app's own).
// The service's int64 fields are plain values here, so what a page loads is JSON: a revision is its digits,
// a count a number.
import { procedure } from "@conusai-kit/core"
import { z } from "zod"
import { CATALOG_PERMISSIONS, IMPORT_CHUNK_ROWS, PRODUCT_SEARCH_FIELDS } from "./constants.js"
const inProject = { org: z.string(), workspace: z.string(), project: z.string() }
const page = { after: z.string().max(64).optional(), limit: z.number().int().min(1).max(200).optional() }
/** What a form generates once per submission, so a retried request applies once. */
const requestId = z.string().uuid()
const productId = z.string().min(1).max(64)
/** A revision as its digits: the service's are 64-bit. */
const revision = z.string().regex(/^\d{1,19}$/)
export const productViewSchema = z.object({
productId: z.string(),
code: z.string(),
name: z.string(),
description: z.string(),
/** A UN/CEFACT Recommendation 20 unit code. */
baseUnit: z.string(),
status: z.enum(["active", "archived", "deleted"]),
groupCode: z.string().nullable(),
identifiers: z.array(z.object({ kind: z.string(), value: z.string() })),
revision,
})
export type ProductView = z.output<typeof productViewSchema>
export const importViewSchema = z.object({
importId: z.string(),
sourceName: z.string(),
format: z.string(),
status: z.string(),
revision,
created: z.number().int(),
updated: z.number().int(),
unchanged: z.number().int(),
refused: z.number().int(),
})
export type ImportView = z.output<typeof importViewSchema>
export const importOutcomeSchema = z.object({
import: importViewSchema,
rows: z.array(
z.object({
sourceRow: z.number().int(),
outcome: z.string(),
productId: z.string().nullable(),
reason: z.string().nullable(),
}),
),
})
export type ImportOutcomeView = z.output<typeof importOutcomeSchema>
const importRowSchema = z.object({
/** The line of the source file, which the service keeps as the row's provenance. */
sourceRow: z.number().int().min(1),
/** The revision the row replaces, for a product that exists. */
revision: revision.optional(),
product: z.object({
code: z.string().min(1).max(64),
name: z.string().min(1).max(200),
baseUnit: z.string().min(1).max(3),
description: z.string().max(4000).optional(),
}),
})
export type ImportRow = z.output<typeof importRowSchema>
const productPage = z.object({ rows: z.array(productViewSchema), after: z.string().optional() })
export const productList = procedure("catalog.product.list")
.kind("read")
.scope("project")
.permission(CATALOG_PERMISSIONS.read)
.input(z.object({ ...inProject, ...page }))
.output(productPage)
.contract()
const searchField = z.enum(PRODUCT_SEARCH_FIELDS)
export type ProductSearchField = z.output<typeof searchField>
export const productSearch = procedure("catalog.product.search")
.kind("read")
.scope("project")
.permission(CATALOG_PERMISSIONS.read)
.input(z.object({ ...inProject, q: z.string().trim().min(1).max(200), by: searchField.optional(), ...page }))
.output(productPage)
.contract()
export const productGet = procedure("catalog.product.get")
.kind("read")
.scope("project")
.permission(CATALOG_PERMISSIONS.read)
.input(z.object({ ...inProject, productId }))
.output(productViewSchema)
.contract()
export const importList = procedure("catalog.import.list")
.kind("read")
.scope("project")
.permission(CATALOG_PERMISSIONS.read)
.input(z.object({ ...inProject, ...page }))
.output(z.object({ rows: z.array(importViewSchema), after: z.string().optional() }))
.contract()
export const importApply = procedure("catalog.import.apply")
.kind("effect")
.scope("project")
.permission(CATALOG_PERMISSIONS.write)
.input(
z.object({
...inProject,
/** The source file's lower-case SHA-256: one file is one import, however many chunks it takes. */
fileHash: z.string().regex(/^[0-9a-f]{64}$/),
sourceName: z.string().trim().min(1).max(200),
format: z.enum(["csv", "xlsx", "json"]),
chunk: z.number().int().min(0),
finalChunk: z.boolean(),
/** The revision of the import, from the chunk before; absent on the first. */
revision: revision.optional(),
rows: z.array(importRowSchema).min(1).max(IMPORT_CHUNK_ROWS),
requestId,
}),
)
.output(importOutcomeSchema)
.contract()