feat: fix extra urls for projects/deployments/consumers models

pull/715/head
Travis Fischer 2025-06-28 02:56:55 -05:00
rodzic 2b5c389045
commit d06b0f5572
32 zmienionych plików z 395 dodań i 329 usunięć

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerAdminSelectSchema } from '@/db/schema'
import { aclAdmin } from '@/lib/acl-admin'
import {
openapiAuthenticatedSecuritySchemas,
@ -58,6 +57,6 @@ export function registerV1AdminActivateConsumer(
assert(consumer, 404, `Consumer not found "${consumerId}"`)
setAdminCacheControlForConsumer(c, consumer)
return c.json(parseConsumerAdminSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerAdminSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerAdminSelectSchema } from '@/db/schema'
import { aclAdmin } from '@/lib/acl-admin'
import {
openapiAuthenticatedSecuritySchemas,
@ -56,6 +55,6 @@ export function registerV1AdminGetConsumerByToken(
assert(consumer, 404, `API token not found "${token}"`)
setAdminCacheControlForConsumer(c, consumer)
return c.json(parseConsumerAdminSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerAdminSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { pick } from '@agentic/platform-core'
import { parseZodSchema, pick } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { upsertConsumerStripeCheckout } from '@/lib/consumers/upsert-consumer-stripe-checkout'
import {
openapiAuthenticatedSecuritySchemas,
@ -65,7 +64,7 @@ export function registerV1CreateConsumerCheckoutSession(
return c.json({
checkoutSession: pick(checkoutSession, 'id', 'url'),
consumer: parseConsumerSelectSchema(consumer)
consumer: parseZodSchema(schema.consumerSelectSchema, consumer)
})
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { upsertConsumer } from '@/lib/consumers/upsert-consumer'
import {
openapiAuthenticatedSecuritySchemas,
@ -53,6 +53,6 @@ export function registerV1CreateConsumer(
const body = c.req.valid('json')
const consumer = await upsertConsumer(c, body)
return c.json(parseConsumerSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { and, db, eq, schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { aclPublicProject } from '@/lib/acl-public-project'
import {
@ -68,6 +67,6 @@ export function registerV1GetConsumerByProjectIdentifier(
)
await acl(c, consumer, { label: 'Consumer' })
return c.json(parseConsumerSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import {
openapiAuthenticatedSecuritySchemas,
@ -52,6 +51,6 @@ export function registerV1GetConsumer(app: OpenAPIHono<AuthenticatedHonoEnv>) {
assert(consumer, 404, `Consumer not found "${consumerId}"`)
await acl(c, consumer, { label: 'Consumer' })
return c.json(parseConsumerSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerSelectArraySchema } from '@/db/schema'
import { ensureAuthUser } from '@/lib/ensure-auth-user'
import {
openapiAuthenticatedSecuritySchemas,
@ -62,6 +62,8 @@ export function registerV1ListConsumers(
limit
})
return c.json(parseConsumerSelectArraySchema(consumers))
return c.json(
parseZodSchema(z.array(schema.consumerSelectSchema), consumers)
)
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerSelectArraySchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import {
openapiAuthenticatedSecuritySchemas,
@ -72,6 +71,8 @@ export function registerV1ListConsumersForProject(
limit
})
return c.json(parseConsumerSelectArraySchema(consumers))
return c.json(
parseZodSchema(z.array(schema.consumerSelectSchema), consumers)
)
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { createConsumerToken } from '@/lib/create-consumer-token'
import {
@ -60,6 +59,6 @@ export function registerV1RefreshConsumerToken(
.returning()
assert(consumer, 500, 'Error updating consumer')
return c.json(parseConsumerSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseConsumerSelectSchema } from '@/db/schema'
import { upsertConsumer } from '@/lib/consumers/upsert-consumer'
import {
openapiAuthenticatedSecuritySchemas,
@ -61,6 +61,6 @@ export function registerV1UpdateConsumer(
consumerId
})
return c.json(parseConsumerSelectSchema(consumer))
return c.json(parseZodSchema(schema.consumerSelectSchema, consumer))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseDeploymentAdminSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { aclAdmin } from '@/lib/acl-admin'
import { tryGetDeploymentByIdentifier } from '@/lib/deployments/try-get-deployment-by-identifier'
@ -68,7 +67,7 @@ export function registerV1AdminGetDeploymentByIdentifier(
const hasPopulateProject = populate.includes('project')
return c.json(
parseDeploymentAdminSelectSchema({
parseZodSchema(schema.deploymentAdminSelectSchema, {
...deployment,
...(hasPopulateProject ? { project } : {}),
_secret: project._secret

Wyświetl plik

@ -1,5 +1,5 @@
import { resolveAgenticProjectConfig } from '@agentic/platform'
import { assert, sha256, slugify } from '@agentic/platform-core'
import { assert, parseZodSchema, sha256, slugify } from '@agentic/platform-core'
import {
isValidDeploymentIdentifier,
parseProjectIdentifier
@ -8,7 +8,6 @@ import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { normalizeDeploymentVersion } from '@/lib/deployments/normalize-deployment-version'
import { publishDeployment } from '@/lib/deployments/publish-deployment'
@ -190,6 +189,6 @@ export function registerV1CreateDeployment(
})
}
return c.json(parseDeploymentSelectSchema(deployment))
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { tryGetDeploymentByIdentifier } from '@/lib/deployments/try-get-deployment-by-identifier'
import {
@ -54,6 +53,6 @@ export function registerV1GetDeploymentByIdentifier(
assert(deployment, 404, `Deployment not found "${deploymentIdentifier}"`)
await acl(c, deployment, { label: 'Deployment' })
return c.json(parseDeploymentSelectSchema(deployment))
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { getDeploymentById } from '@/lib/deployments/get-deployment-by-id'
import {
@ -55,6 +54,6 @@ export function registerV1GetDeployment(
assert(deployment, 404, `Deployment not found "${deploymentId}"`)
await acl(c, deployment, { label: 'Deployment' })
return c.json(parseDeploymentSelectSchema(deployment))
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import type { DefaultHonoEnv } from '@agentic/platform-hono'
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import { schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { aclPublicProject } from '@/lib/acl-public-project'
import { tryGetDeploymentByIdentifier } from '@/lib/deployments/try-get-deployment-by-identifier'
import {
@ -60,6 +59,6 @@ export function registerV1GetPublicDeploymentByIdentifier(
)
aclPublicProject(deployment.project!)
return c.json(parseDeploymentSelectSchema(deployment))
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { and, db, eq, schema } from '@/db'
import { parseDeploymentSelectArraySchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { ensureAuthUser } from '@/lib/ensure-auth-user'
import {
@ -88,6 +88,8 @@ export function registerV1ListDeployments(
limit
})
return c.json(parseDeploymentSelectArraySchema(deployments))
return c.json(
parseZodSchema(z.array(schema.deploymentSelectSchema), deployments)
)
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { getDeploymentById } from '@/lib/deployments/get-deployment-by-id'
import { publishDeployment } from '@/lib/deployments/publish-deployment'
@ -64,6 +63,8 @@ export function registerV1PublishDeployment(
version
})
return c.json(parseDeploymentSelectSchema(publishedDeployment))
return c.json(
parseZodSchema(schema.deploymentSelectSchema, publishedDeployment)
)
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseDeploymentSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import { getDeploymentById } from '@/lib/deployments/get-deployment-by-id'
import {
@ -66,6 +65,6 @@ export function registerV1UpdateDeployment(
.returning()
assert(deployment, 500, `Failed to update deployment "${deploymentId}"`)
return c.json(parseDeploymentSelectSchema(deployment))
return c.json(parseZodSchema(schema.deploymentSelectSchema, deployment))
})
}

Wyświetl plik

@ -1,10 +1,9 @@
import { assert, sha256 } from '@agentic/platform-core'
import { assert, parseZodSchema, sha256 } from '@agentic/platform-core'
import { parseProjectIdentifier } from '@agentic/platform-validators'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { ensureAuthUser } from '@/lib/ensure-auth-user'
import { env } from '@/lib/env'
import {
@ -87,6 +86,6 @@ export function registerV1CreateProject(
.returning()
assert(project, 500, `Failed to create project "${body.name}"`)
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import {
openapiAuthenticatedSecuritySchemas,
@ -54,6 +53,6 @@ export function registerV1GetProjectByIdentifier(
assert(project, 404, `Project not found "${projectIdentifier}"`)
await acl(c, project, { label: 'Project' })
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import {
openapiAuthenticatedSecuritySchemas,
@ -53,6 +52,6 @@ export function registerV1GetProject(app: OpenAPIHono<AuthenticatedHonoEnv>) {
assert(project, 404, `Project not found "${projectId}"`)
await acl(c, project, { label: 'Project' })
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import type { DefaultHonoEnv } from '@agentic/platform-hono'
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import { db, eq, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { aclPublicProject } from '@/lib/acl-public-project'
import {
openapiAuthenticatedSecuritySchemas,
@ -50,8 +50,8 @@ export function registerV1GetPublicProjectByIdentifier(
...Object.fromEntries(populate.map((field) => [field, true]))
}
})
aclPublicProject(project, projectIdentifier)
await aclPublicProject(project, projectIdentifier)
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import type { DefaultHonoEnv } from '@agentic/platform-hono'
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import { db, eq, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { aclPublicProject } from '@/lib/acl-public-project'
import {
openapiAuthenticatedSecuritySchemas,
@ -51,6 +51,6 @@ export function registerV1GetPublicProject(app: OpenAPIHono<DefaultHonoEnv>) {
})
aclPublicProject(project, projectId)
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseProjectSelectArraySchema } from '@/db/schema'
import { ensureAuthUser } from '@/lib/ensure-auth-user'
import {
openapiAuthenticatedSecuritySchemas,
@ -65,6 +65,6 @@ export function registerV1ListProjects(app: OpenAPIHono<AuthenticatedHonoEnv>) {
limit
})
return c.json(parseProjectSelectArraySchema(projects))
return c.json(parseZodSchema(z.array(schema.projectSelectSchema), projects))
})
}

Wyświetl plik

@ -1,8 +1,8 @@
import type { DefaultHonoEnv } from '@agentic/platform-hono'
import { parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono, z } from '@hono/zod-openapi'
import { and, db, eq, isNotNull, schema } from '@/db'
import { parseProjectSelectArraySchema } from '@/db/schema'
import {
openapiAuthenticatedSecuritySchemas,
openapiErrorResponses
@ -61,6 +61,6 @@ export function registerV1ListPublicProjects(app: OpenAPIHono<DefaultHonoEnv>) {
limit
})
return c.json(parseProjectSelectArraySchema(projects))
return c.json(parseZodSchema(z.array(schema.projectSelectSchema), projects))
})
}

Wyświetl plik

@ -1,9 +1,8 @@
import { assert } from '@agentic/platform-core'
import { assert, parseZodSchema } from '@agentic/platform-core'
import { createRoute, type OpenAPIHono } from '@hono/zod-openapi'
import type { AuthenticatedHonoEnv } from '@/lib/types'
import { db, eq, schema } from '@/db'
import { parseProjectSelectSchema } from '@/db/schema'
import { acl } from '@/lib/acl'
import {
openapiAuthenticatedSecuritySchemas,
@ -67,6 +66,6 @@ export function registerV1UpdateProject(
.returning()
assert(project, 500, `Failed to update project "${projectId}"`)
return c.json(parseProjectSelectSchema(project))
return c.json(parseZodSchema(schema.projectSelectSchema, project))
})
}

Wyświetl plik

@ -1,4 +1,3 @@
import { parseZodSchema } from '@agentic/platform-core'
import {
type StripeSubscriptionItemIdMap,
stripeSubscriptionItemIdMapSchema
@ -15,7 +14,6 @@ import { z } from '@hono/zod-openapi'
import { env } from '@/lib/env'
import type { Consumer } from '../types'
import {
consumerIdSchema,
deploymentIdSchema,
@ -142,7 +140,7 @@ export const consumersRelations = relations(consumers, ({ one }) => ({
})
}))
export const consumerSelectSchema = createSelectSchema(consumers, {
export const consumerSelectBaseSchema = createSelectSchema(consumers, {
id: consumerIdSchema,
userId: userIdSchema,
projectId: projectIdSchema,
@ -188,22 +186,29 @@ export const consumerSelectSchema = createSelectSchema(consumers, {
})
.optional()
})
.strip()
// These are all derived virtual URLs that are not stored in the database
.extend({
/**
* A private admin URL for managing the customer's subscription. This URL
* is only accessible by the customer.
*
* @example https://agentic.so/app/consumers/cons_123
*/
adminUrl: z
.string()
.url()
.describe(
"A private admin URL for managing the customer's subscription. This URL is only accessible by the customer."
)
})
// These are all derived virtual URLs that are not stored in the database
export const derivedConsumerFields = {
/**
* A private admin URL for managing the customer's subscription. This URL
* is only accessible by the customer.
*
* @example https://agentic.so/app/consumers/cons_123
*/
adminUrl: z
.string()
.url()
.describe(
"A private admin URL for managing the customer's subscription. This URL is only accessible by the customer."
)
} as const
export const consumerSelectSchema = consumerSelectBaseSchema
.transform((consumer) => ({
...consumer,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/consumers/${consumer.id}`
}))
.pipe(consumerSelectBaseSchema.extend(derivedConsumerFields).strip())
.describe(
`A Consumer represents a user who has subscribed to a Project and is used
to track usage and billing.
@ -215,36 +220,16 @@ owner's connected Stripe account if the project has Stripe Connect enabled.`
)
.openapi('Consumer')
export function parseConsumerSelectSchema(
consumer: Record<string, any>
): Consumer {
return parseZodSchema(consumerSelectSchema, {
...consumer,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/consumers/${consumer.id}`
})
}
export function parseConsumerSelectArraySchema(
consumers: Record<string, any>[]
): Consumer[] {
return consumers.map(parseConsumerSelectSchema)
}
export const consumerAdminSelectSchema = consumerSelectSchema
export const consumerAdminSelectSchema = consumerSelectBaseSchema
.extend({
_stripeCustomerId: z.string().nonempty()
})
.transform((consumer) => ({
...consumer,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/consumers/${consumer.id}`
}))
.openapi('AdminConsumer')
export function parseConsumerAdminSelectSchema(
consumer: Record<string, any>
): Consumer {
return parseZodSchema(consumerAdminSelectSchema, {
...parseConsumerSelectSchema(consumer),
...consumer
})
}
export const consumerInsertSchema = createInsertSchema(consumers, {
deploymentId: deploymentIdSchema.optional(),

Wyświetl plik

@ -1,4 +1,3 @@
import { parseZodSchema } from '@agentic/platform-core'
import {
agenticProjectConfigSchema,
defaultRequestsRateLimit,
@ -26,7 +25,6 @@ import { z } from '@hono/zod-openapi'
import { env } from '@/lib/env'
import type { Deployment } from '../types'
import {
deploymentIdentifierSchema,
deploymentIdSchema,
@ -153,7 +151,7 @@ export const deploymentsRelations = relations(deployments, ({ one }) => ({
// TODO: virtual authProviders?
// TODO: virtual openapi spec? (hide openapi.servers)
export const deploymentSelectSchema = createSelectSchema(deployments, {
export const deploymentSelectBaseSchema = createSelectSchema(deployments, {
id: deploymentIdSchema,
userId: userIdSchema,
teamId: teamIdSchema.optional(),
@ -215,60 +213,75 @@ export const deploymentSelectSchema = createSelectSchema(deployments, {
// TODO: Circular references make this schema less than ideal
// project: z.object({}).optional().openapi('Project', { type: 'object' })
})
.strip()
// These are all derived virtual URLs that are not stored in the database
.extend({
/**
* The public base HTTP URL for the deployment supporting HTTP POST requests
* for individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.com/@agentic/search@latest
*/
gatewayBaseUrl: z
.string()
.url()
.describe(
'The public base HTTP URL for the deployment supporting HTTP POST requests for individual tools at `/tool-name` subpaths.'
),
/**
* The public MCP URL for the deployment supporting the Streamable HTTP
* transport.
*
* @example https://gateway.agentic.com/@agentic/search@latest/mcp
*/
gatewayMcpUrl: z
.string()
.url()
.describe(
'The public MCP URL for the deployment supporting the Streamable HTTP transport.'
),
// These are all derived virtual URLs that are not stored in the database
export const derivedDeploymentFields = {
/**
* The public base HTTP URL for the deployment supporting HTTP POST requests
* for individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.so/@agentic/search@latest
*/
gatewayBaseUrl: z
.string()
.url()
.describe(
'The public base HTTP URL for the deployment supporting HTTP POST requests for individual tools at `/tool-name` subpaths.'
),
/**
* The public marketplace URL for the deployment's project.
*
* Note that only published deployments are visible on the marketplace.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: z
.string()
.url()
.describe("The public marketplace URL for the deployment's project."),
/**
* The public MCP URL for the deployment supporting the Streamable HTTP
* transport.
*
* @example https://gateway.agentic.so/@agentic/search@latest/mcp
*/
gatewayMcpUrl: z
.string()
.url()
.describe(
'The public MCP URL for the deployment supporting the Streamable HTTP transport.'
),
/**
* A private admin URL for managing the deployment. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search/deployments/123
*/
adminUrl: z
.string()
.url()
.describe(
'A private admin URL for managing the deployment. This URL is only accessible by project owners.'
)
/**
* The public marketplace URL for the deployment's project.
*
* Note that only published deployments are visible on the marketplace.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: z
.string()
.url()
.describe("The public marketplace URL for the deployment's project."),
/**
* A private admin URL for managing the deployment. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search/deployments/123
*/
adminUrl: z
.string()
.url()
.describe(
'A private admin URL for managing the deployment. This URL is only accessible by project owners.'
)
} as const
export const deploymentSelectSchema = deploymentSelectBaseSchema
.transform((deployment) => {
const { projectIdentifier, deploymentIdentifier } =
parseDeploymentIdentifier(deployment.identifier)
return {
...deployment,
gatewayBaseUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}`,
gatewayMcpUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}/mcp`,
marketplaceUrl: `${env.AGENTIC_WEB_BASE_URL}/marketplace/projects/${projectIdentifier}`,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/projects/${projectIdentifier}/deployments/${deployment.hash}`
}
})
.pipe(deploymentSelectBaseSchema.extend(derivedDeploymentFields).strip())
.describe(
`A Deployment is a single, immutable instance of a Project. Each deployment contains pricing plans, origin server config (OpenAPI or MCP server), tool definitions, and metadata.
@ -276,43 +289,24 @@ Deployments are private to a developer or team until they are published, at whic
)
.openapi('Deployment')
export function parseDeploymentSelectSchema(
deployment: Record<string, any>
): Deployment {
const { projectIdentifier, deploymentIdentifier } = parseDeploymentIdentifier(
deployment.identifier
)
return parseZodSchema(deploymentSelectSchema, {
...deployment,
gatewayBaseUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}`,
gatewayMcpUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}/mcp`,
marketplaceUrl: `${env.AGENTIC_WEB_BASE_URL}/marketplace/projects/${projectIdentifier}`,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/projects/${projectIdentifier}/deployments/${deployment.hash}`
})
}
export function parseDeploymentSelectArraySchema(
deployments: Record<string, any>[]
): Deployment[] {
return deployments.map(parseDeploymentSelectSchema)
}
export const deploymentAdminSelectSchema = deploymentSelectSchema
export const deploymentAdminSelectSchema = deploymentSelectBaseSchema
.extend({
origin: resolvedAgenticProjectConfigSchema.shape.origin,
_secret: z.string().nonempty()
})
.openapi('AdminDeployment')
.transform((deployment) => {
const { projectIdentifier, deploymentIdentifier } =
parseDeploymentIdentifier(deployment.identifier)
export function parseDeploymentAdminSelectSchema(
deployment: Record<string, any>
): z.infer<typeof deploymentAdminSelectSchema> {
return parseZodSchema(deploymentAdminSelectSchema, {
...parseDeploymentSelectSchema(deployment),
...deployment
return {
...deployment,
gatewayBaseUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}`,
gatewayMcpUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${deploymentIdentifier}/mcp`,
marketplaceUrl: `${env.AGENTIC_WEB_BASE_URL}/marketplace/projects/${projectIdentifier}`,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/projects/${projectIdentifier}/deployments/${deployment.hash}`
}
})
}
.openapi('AdminDeployment')
export const deploymentInsertSchema = agenticProjectConfigSchema.strict()

Wyświetl plik

@ -1,4 +1,3 @@
import { parseZodSchema } from '@agentic/platform-core'
import {
agenticProjectConfigSchema,
pricingIntervalSchema,
@ -23,7 +22,6 @@ import { z } from '@hono/zod-openapi'
import { env } from '@/lib/env'
import type { Project } from '../types'
import {
deploymentIdSchema,
projectIdentifierSchema,
@ -210,7 +208,7 @@ export const projectsRelations = relations(projects, ({ one }) => ({
// })
}))
export const projectSelectSchema = createSelectSchema(projects, {
export const projectSelectBaseSchema = createSelectSchema(projects, {
id: projectIdSchema,
userId: userIdSchema,
teamId: teamIdSchema.optional(),
@ -296,57 +294,67 @@ export const projectSelectSchema = createSelectSchema(projects, {
})
.optional()
})
.strip()
// These are all derived virtual URLs that are not stored in the database
.extend({
/**
* The public base HTTP URL for the project supporting HTTP POST requests for
* individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.com/@agentic/search
*/
gatewayBaseUrl: z
.string()
.url()
.describe(
'The public base HTTP URL for the project supporting HTTP POST requests for individual tools at `/tool-name` subpaths.'
),
/**
* The public MCP URL for the project supporting the Streamable HTTP transport.
*
* @example https://gateway.agentic.com/@agentic/search/mcp
*/
gatewayMcpUrl: z
.string()
.url()
.describe(
'The public MCP URL for the project supporting the Streamable HTTP transport.'
),
// These are all derived virtual URLs that are not stored in the database
export const derivedProjectFields = {
/**
* The public base HTTP URL for the project supporting HTTP POST requests for
* individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.so/@agentic/search
*/
gatewayBaseUrl: z
.string()
.url()
.describe(
'The public base HTTP URL for the project supporting HTTP POST requests for individual tools at `/tool-name` subpaths.'
),
/**
* The public marketplace URL for the project.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: z
.string()
.url()
.describe('The public marketplace URL for the project.'),
/**
* The public MCP URL for the project supporting the Streamable HTTP transport.
*
* @example https://gateway.agentic.so/@agentic/search/mcp
*/
gatewayMcpUrl: z
.string()
.url()
.describe(
'The public MCP URL for the project supporting the Streamable HTTP transport.'
),
/**
* A private admin URL for managing the project. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search
*/
adminUrl: z
.string()
.url()
.describe(
'A private admin URL for managing the project. This URL is only accessible by project owners.'
)
})
/**
* The public marketplace URL for the project.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: z
.string()
.url()
.describe('The public marketplace URL for the project.'),
/**
* A private admin URL for managing the project. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search
*/
adminUrl: z
.string()
.url()
.describe(
'A private admin URL for managing the project. This URL is only accessible by project owners.'
)
} as const
export const projectSelectSchema = projectSelectBaseSchema
.transform((project) => ({
...project,
gatewayBaseUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${project.identifier}`,
gatewayMcpUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${project.identifier}/mcp`,
marketplaceUrl: `${env.AGENTIC_WEB_BASE_URL}/marketplace/projects/${project.identifier}`,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/projects/${project.identifier}`
}))
.pipe(projectSelectBaseSchema.extend(derivedProjectFields).strip())
.describe(
`A Project represents a single Agentic API product. It is comprised of a series of immutable Deployments, each of which contains pricing data, origin API config, OpenAPI or MCP specs, tool definitions, and various metadata.
@ -356,24 +364,6 @@ Internally, Projects manage all of the Stripe billing resources across Deploymen
)
.openapi('Project')
export function parseProjectSelectSchema(
project: Record<string, any>
): Project {
return parseZodSchema(projectSelectSchema, {
...project,
gatewayBaseUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${project.identifier}`,
gatewayMcpUrl: `${env.AGENTIC_GATEWAY_BASE_URL}/${project.identifier}/mcp`,
marketplaceUrl: `${env.AGENTIC_WEB_BASE_URL}/marketplace/projects/${project.identifier}`,
adminUrl: `${env.AGENTIC_WEB_BASE_URL}/app/projects/${project.identifier}`
})
}
export function parseProjectSelectArraySchema(
projects: Record<string, any>[]
): Project[] {
return projects.map(parseProjectSelectSchema)
}
export const projectInsertSchema = createInsertSchema(projects, {
identifier: projectIdentifierSchema,

Wyświetl plik

@ -14,5 +14,3 @@ description: Agentic is the App Store for LLM Tools.
service to Agentic.
</Card>
</Columns>
**TODO**

Wyświetl plik

@ -622,26 +622,6 @@ export interface components {
lastPublishedDeployment?: unknown;
lastDeployment?: unknown;
deployment?: unknown;
/**
* Format: uri
* @description The public base HTTP URL for the project supporting HTTP POST requests for individual tools at `/tool-name` subpaths.
*/
gatewayBaseUrl: string;
/**
* Format: uri
* @description The public MCP URL for the project supporting the Streamable HTTP transport.
*/
gatewayMcpUrl: string;
/**
* Format: uri
* @description The public marketplace URL for the project.
*/
marketplaceUrl: string;
/**
* Format: uri
* @description A private admin URL for managing the project. This URL is only accessible by project owners.
*/
adminUrl: string;
};
/** @description Public deployment identifier (e.g. "@namespace/project-slug@{hash|version|latest}") */
DeploymentIdentifier: string;
@ -834,26 +814,6 @@ export interface components {
pricingIntervals: components["schemas"]["PricingInterval"][];
defaultRateLimit?: components["schemas"]["RateLimit"] & unknown;
project?: unknown;
/**
* Format: uri
* @description The public base HTTP URL for the deployment supporting HTTP POST requests for individual tools at `/tool-name` subpaths.
*/
gatewayBaseUrl: string;
/**
* Format: uri
* @description The public MCP URL for the deployment supporting the Streamable HTTP transport.
*/
gatewayMcpUrl: string;
/**
* Format: uri
* @description The public marketplace URL for the deployment's project.
*/
marketplaceUrl: string;
/**
* Format: uri
* @description A private admin URL for managing the deployment. This URL is only accessible by project owners.
*/
adminUrl: string;
};
TeamMember: {
createdAt: string;
@ -895,11 +855,6 @@ export interface components {
user?: components["schemas"]["User"];
project?: components["schemas"]["Project"];
deployment?: unknown;
/**
* Format: uri
* @description A private admin URL for managing the customer's subscription. This URL is only accessible by the customer.
*/
adminUrl: string;
};
/** @description Origin adapter is used to configure the origin API server downstream from Agentic's API gateway. It specifies whether the origin API server denoted by `url` is hosted externally or deployed internally to Agentic's infrastructure. It also specifies the format for how origin tools are defined: either an OpenAPI spec or an MCP server.
*
@ -952,14 +907,27 @@ export interface components {
/** @enum {string} */
type: "raw";
};
/** @description A Consumer represents a user who has subscribed to a Project and is used
* to track usage and billing.
*
* Consumers are linked to a corresponding Stripe Customer and Subscription.
* The Stripe customer will either be the user's default Stripe Customer if the
* project uses the default Agentic platform account, or a customer on the project
* owner's connected Stripe account if the project has Stripe Connect enabled. */
AdminConsumer: components["schemas"]["Consumer"] & {
AdminConsumer: {
/** @description Consumer id (e.g. "csmr_tz4a98xxat96iws9zmbrgj3a") */
id: string;
createdAt: string;
updatedAt: string;
deletedAt?: string;
token: string;
plan?: string;
activated: boolean;
source?: string;
/** @description User id (e.g. "user_tz4a98xxat96iws9zmbrgj3a") */
userId: string;
/** @description Project id (e.g. "proj_tz4a98xxat96iws9zmbrgj3a") */
projectId: string;
/** @description Deployment id (e.g. "depl_tz4a98xxat96iws9zmbrgj3a") */
deploymentId: string;
stripeStatus: string;
isStripeSubscriptionActive: boolean;
user?: components["schemas"]["User"];
project?: components["schemas"]["Project"];
deployment?: unknown;
_stripeCustomerId: string;
};
/** @description Origin adapter is used to configure the origin API server downstream from Agentic's API gateway. It specifies whether the origin API server denoted by `url` is hosted externally or deployed internally to Agentic's infrastructure. It also specifies the format for how origin tools are defined: either an OpenAPI spec, an MCP server, or a raw HTTP REST API. */
@ -1047,10 +1015,77 @@ export interface components {
/** @enum {string} */
type: "raw";
};
/** @description A Deployment is a single, immutable instance of a Project. Each deployment contains pricing plans, origin server config (OpenAPI or MCP server), tool definitions, and metadata.
*
* Deployments are private to a developer or team until they are published, at which point they are accessible to any customers with access to the parent Project. */
AdminDeployment: components["schemas"]["Deployment"] & {
AdminDeployment: {
/** @description Deployment id (e.g. "depl_tz4a98xxat96iws9zmbrgj3a") */
id: string;
createdAt: string;
updatedAt: string;
deletedAt?: string;
identifier: components["schemas"]["DeploymentIdentifier"];
hash: string;
/** @description Optional semantic version of the project as a semver string. Ex: 1.0.0, 0.0.1, 5.0.1, etc. */
version?: string;
published: boolean;
/** @description A short description of the project. */
description?: string;
/** @description A readme documenting the project (supports GitHub-flavored markdown). */
readme?: string;
/**
* Format: uri
* @description Optional logo image URL to use for the project. Logos should have a square aspect ratio.
*/
iconUrl?: string;
/**
* Format: uri
* @description Optional URL to the source code of the project (eg, GitHub repo).
*/
sourceUrl?: string;
/** @description User id (e.g. "user_tz4a98xxat96iws9zmbrgj3a") */
userId: string;
/** @description Team id (e.g. "team_tz4a98xxat96iws9zmbrgj3a") */
teamId?: string;
/** @description Project id (e.g. "proj_tz4a98xxat96iws9zmbrgj3a") */
projectId: string;
/** @default [] */
tools: components["schemas"]["Tool"][];
/** @default [] */
toolConfigs: components["schemas"]["ToolConfig"][];
/**
* @description List of PricingPlans configuring which Stripe subscriptions should be available for the project. Defaults to a single free plan which is useful for developing and testing your project.
* @default [
* {
* "name": "Free",
* "slug": "free",
* "lineItems": [
* {
* "slug": "base",
* "usageType": "licensed",
* "amount": 0
* }
* ],
* "rateLimit": {
* "enabled": true,
* "interval": 60,
* "limit": 1000,
* "mode": "approximate"
* }
* }
* ]
*/
pricingPlans: components["schemas"]["PricingPlan"][];
/**
* @description Optional list of billing intervals to enable in the pricingPlans.
*
* Defaults to a single monthly interval `['month']`.
*
* To add support for annual pricing plans, for example, you can use: `['month', 'year']`.
* @default [
* "month"
* ]
*/
pricingIntervals: components["schemas"]["PricingInterval"][];
defaultRateLimit?: components["schemas"]["RateLimit"] & unknown;
project?: unknown;
origin: components["schemas"]["OriginAdapter"];
_secret: string;
};

Wyświetl plik

@ -27,6 +27,14 @@ export type Consumer = Simplify<
user?: User
project?: Project
deployment?: Deployment
/**
* A private admin URL for managing the customer's subscription. This URL
* is only accessible by the customer.
*
* @example https://agentic.so/app/consumers/cons_123
*/
adminUrl: string
}
>
export type Project = Simplify<
@ -35,6 +43,36 @@ export type Project = Simplify<
team?: Team
lastPublishedDeployment?: Deployment
lastDeployment?: Deployment
/**
* The public base HTTP URL for the project supporting HTTP POST requests for
* individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.so/@agentic/search
*/
gatewayBaseUrl: string
/**
* The public MCP URL for the project supporting the Streamable HTTP transport.
*
* @example https://gateway.agentic.so/@agentic/search/mcp
*/
gatewayMcpUrl: string
/**
* The public marketplace URL for the project.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: string
/**
* A private admin URL for managing the project. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search
*/
adminUrl: string
}
>
export type Deployment = Simplify<
@ -46,6 +84,39 @@ export type Deployment = Simplify<
toolConfigs: ToolConfig[]
defaultRateLimit: RateLimit
project?: components['schemas']['Project']
/**
* The public base HTTP URL for the deployment supporting HTTP POST requests
* for individual tools at `/tool-name` subpaths.
*
* @example https://gateway.agentic.so/@agentic/search@latest
*/
gatewayBaseUrl: string
/**
* The public MCP URL for the deployment supporting the Streamable HTTP
* transport.
*
* @example https://gateway.agentic.so/@agentic/search@latest/mcp
*/
gatewayMcpUrl: string
/**
* The public marketplace URL for the deployment's project.
*
* Note that only published deployments are visible on the marketplace.
*
* @example https://agentic.so/marketplace/projects/@agentic/search
*/
marketplaceUrl: string
/**
* A private admin URL for managing the deployment. This URL is only accessible
* by project owners.
*
* @example https://agentic.so/app/projects/@agentic/search/deployments/123
*/
adminUrl: string
}
>
@ -59,7 +130,10 @@ export type AdminDeployment = Simplify<
defaultRateLimit: RateLimit
origin: OriginAdapter
project?: components['schemas']['Project']
}
} & Pick<
Deployment,
'gatewayBaseUrl' | 'gatewayMcpUrl' | 'marketplaceUrl' | 'adminUrl'
>
>
export type AdminConsumer = Simplify<
@ -67,7 +141,7 @@ export type AdminConsumer = Simplify<
user?: User
project?: Project
deployment?: Deployment
}
} & Pick<Consumer, 'adminUrl'>
>
export type AgenticMcpRequestMetadata = {