kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
f539c7ed38
commit
f55ba7f060
|
@ -26,6 +26,16 @@ import {
|
|||
// This may require a separate model to aggregate User Applications.
|
||||
// https://docs.rapidapi.com/docs/keys#section-different-api-keys-per-application
|
||||
|
||||
/**
|
||||
* A `Consumer` is a user who has subscribed to a `Project`.
|
||||
*
|
||||
* Consumers are used to track usage and billing for a project.
|
||||
*
|
||||
* Consumers are linked to a corresponding Stripe Customer. The Stripe customer
|
||||
* will either be the user's default Stripe Customer for the platform account,
|
||||
* or a customer on the project's connected Stripe account if the project has
|
||||
* Stripe Connect enabled.
|
||||
*/
|
||||
export const consumers = pgTable(
|
||||
'consumers',
|
||||
{
|
||||
|
@ -34,9 +44,15 @@ export const consumers = pgTable(
|
|||
|
||||
// API token for this consumer
|
||||
token: text().notNull(),
|
||||
|
||||
// The stripe subscription plan this consumer is subscribed to (or 'free' if supported)
|
||||
plan: text(),
|
||||
|
||||
// Whether the consumer has made at least one successful API call after
|
||||
// initializing their subscription.
|
||||
activated: boolean().default(false).notNull(),
|
||||
|
||||
// Whether the consumer's subscription is currently active
|
||||
enabled: boolean().default(true).notNull(),
|
||||
|
||||
env: text().default('dev').notNull(),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { relations } from '@fisch0920/drizzle-orm'
|
||||
import { index, pgTable, text } from '@fisch0920/drizzle-orm/pg-core'
|
||||
import { index, jsonb, pgTable, text } from '@fisch0920/drizzle-orm/pg-core'
|
||||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
import { consumers, consumerSelectSchema } from './consumer'
|
||||
|
@ -12,45 +12,48 @@ import {
|
|||
cuid,
|
||||
deploymentId,
|
||||
id,
|
||||
logEntryLevelEnum,
|
||||
logEntryTypeEnum,
|
||||
projectId,
|
||||
stripeId,
|
||||
timestamps
|
||||
} from './utils'
|
||||
|
||||
/**
|
||||
* A `LogEntry` is an internal audit log entry.
|
||||
*/
|
||||
export const logEntries = pgTable(
|
||||
'log_entries',
|
||||
{
|
||||
id,
|
||||
...timestamps,
|
||||
|
||||
type: text().notNull(),
|
||||
level: text().notNull().default('info'), // TODO: enum
|
||||
// core data (required)
|
||||
type: logEntryTypeEnum().notNull().default('log'),
|
||||
level: logEntryLevelEnum().notNull().default('info'),
|
||||
message: text().notNull(),
|
||||
|
||||
// relations
|
||||
// context info (required)
|
||||
environment: text(),
|
||||
service: text(),
|
||||
requestId: text(),
|
||||
traceId: text(),
|
||||
|
||||
// relations (optional)
|
||||
userId: cuid(),
|
||||
projectId: projectId(),
|
||||
deploymentId: deploymentId(),
|
||||
consumerId: cuid(),
|
||||
|
||||
// (optional) misc context info
|
||||
service: text(),
|
||||
hostname: text(),
|
||||
provider: text(),
|
||||
ip: text(),
|
||||
plan: text(),
|
||||
subtype: text(),
|
||||
|
||||
// (optional) denormalized info
|
||||
username: text(),
|
||||
email: text(),
|
||||
token: text(),
|
||||
|
||||
// (optional) denormalized stripe info
|
||||
stripeCustomer: stripeId(),
|
||||
stripeSubscription: stripeId()
|
||||
// misc metadata (optional)
|
||||
metadata: jsonb().$type<Record<string, unknown>>().default({}).notNull()
|
||||
},
|
||||
(table) => [
|
||||
index('log_entry_type_idx').on(table.type),
|
||||
index('log_entry_level_idx').on(table.level),
|
||||
index('log_entry_environment_idx').on(table.environment),
|
||||
index('log_entry_service_idx').on(table.service),
|
||||
index('log_entry_requestId_idx').on(table.requestId),
|
||||
index('log_entry_traceId_idx').on(table.traceId),
|
||||
index('log_entry_userId_idx').on(table.userId),
|
||||
index('log_entry_projectId_idx').on(table.projectId),
|
||||
index('log_entry_deploymentId_idx').on(table.deploymentId),
|
||||
|
|
|
@ -92,6 +92,14 @@ export const timestamps = {
|
|||
|
||||
export const userRoleEnum = pgEnum('UserRole', ['user', 'admin'])
|
||||
export const teamMemberRoleEnum = pgEnum('TeamMemberRole', ['user', 'admin'])
|
||||
export const logEntryTypeEnum = pgEnum('LogEntryType', ['log'])
|
||||
export const logEntryLevelEnum = pgEnum('LogEntryLevel', [
|
||||
'trace',
|
||||
'debug',
|
||||
'info',
|
||||
'warn',
|
||||
'error'
|
||||
])
|
||||
|
||||
export const { createInsertSchema, createSelectSchema, createUpdateSchema } =
|
||||
createSchemaFactory({
|
||||
|
|
|
@ -1,11 +1,24 @@
|
|||
import { expectTypeOf, test } from 'vitest'
|
||||
|
||||
import type { RawUser, User } from './types'
|
||||
import type { LogLevel } from '@/lib/logger'
|
||||
|
||||
type UserKeys = Exclude<keyof User, 'providers'>
|
||||
import type { LogEntry, RawLogEntry, RawUser, User } from './types'
|
||||
|
||||
type UserKeys = Exclude<keyof User & keyof RawUser, 'providers'>
|
||||
type LogEntryKeys = keyof RawLogEntry & keyof LogEntry
|
||||
|
||||
test('User types are compatible', () => {
|
||||
expectTypeOf<RawUser>().toExtend<User>()
|
||||
|
||||
expectTypeOf<User[UserKeys]>().toEqualTypeOf<RawUser[UserKeys]>()
|
||||
})
|
||||
|
||||
test('LogEntry types are compatible', () => {
|
||||
expectTypeOf<RawLogEntry>().toExtend<LogEntry>()
|
||||
|
||||
expectTypeOf<LogEntry[LogEntryKeys]>().toEqualTypeOf<
|
||||
RawLogEntry[LogEntryKeys]
|
||||
>()
|
||||
|
||||
expectTypeOf<LogEntry['level']>().toEqualTypeOf<LogLevel>()
|
||||
})
|
||||
|
|
|
@ -34,7 +34,7 @@ const server = serve({
|
|||
port: env.PORT
|
||||
})
|
||||
|
||||
initExitHooks({ server })
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Server running on port ${env.PORT}`)
|
||||
|
||||
initExitHooks({ server })
|
||||
|
|
Ładowanie…
Reference in New Issue