Ctrl K
ComunidadGuías…

server/db/schema-authz.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import {
  account,
  accountRelations,
  agent,
  agentCapabilityGrant,
  agentCapabilityGrantRelations,
  agentHost,
  agentHostRelations,
  agentRelations,
  apiResource,
  apiResourceRelations,
  application,
  applicationClientMetadata,
  applicationClientSecret,
  applicationConsent,
  applicationRelations,
  approvalRequest,
  approvalRequestRelations,
  customDomain,
  identityProviderConnector,
  invitation,
  jwks,
  member,
  oauthAccessToken,
  oauthClient,
  oauthConsent,
  oauthRefreshToken,
  organization,
  organizationInvitationRelations,
  organizationMemberRelations,
  organizationRelations,
  organizationRole,
  organizationRoleRelations,
  organizationTeamMemberRelations,
  organizationTeamRelations,
  passkey,
  passkeyRelations,
  session,
  sessionRelations,
  siteSettings,
  twoFactor,
  twoFactorRelations,
  uploadedAsset,
  user,
  userRelations,
  verification,
  webhookDeliveryAttempt,
  webhookDeliveryRequest,
  webhookEndpoint,
} from '@server/db/schema'
import { getTableConfig } from 'drizzle-orm/sqlite-core'
import { describe, expect, it } from 'vitest'

function columnNames(table: Parameters<typeof getTableConfig>[0]) {
  return getTableConfig(table).columns.map((column) => column.name)
}

function indexNames(table: Parameters<typeof getTableConfig>[0]) {
  return getTableConfig(table).indexes.map((index) => index.config.name)
}

function foreignKeyReferences(table: Parameters<typeof getTableConfig>[0]) {
  return getTableConfig(table).foreignKeys.map((foreignKey) => {
    const reference = foreignKey.reference()

    return {
      columns: reference.columns.map((column) => column.name),
      foreignColumns: reference.foreignColumns.map((column) => column.name),
      foreignTable: getTableConfig(reference.foreignTable).name,
      onDelete: foreignKey.onDelete,
    }
  })
}

describe('schema.test 2', () => {
  it('keeps Realmroot product settings and OAuth token tables explicit', () => {
    expect(columnNames(account)).toEqual(expect.arrayContaining(['account_id', 'provider_id', 'user_id']))
    expect(columnNames(verification)).toEqual(expect.arrayContaining(['identifier', 'value', 'expires_at']))
    expect(indexNames(oauthRefreshToken)).toEqual(
      expect.arrayContaining([
        'oauthRefreshToken_clientId_idx',
        'oauthRefreshToken_sessionId_idx',
        'oauthRefreshToken_userId_idx',
      ]),
    )
    const refreshTokenColumns = columnNames(oauthRefreshToken)
    expect(refreshTokenColumns).toEqual(expect.arrayContaining(['token', 'scopes', 'resources']))
    expect(refreshTokenColumns).not.toContain('dpop_jkt')
    expect(refreshTokenColumns).not.toContain('family_id')
    expect(refreshTokenColumns).not.toContain('family_compromised_at')
    expect(indexNames(oauthAccessToken)).toEqual(
      expect.arrayContaining([
        'oauthAccessToken_clientId_idx',
        'oauthAccessToken_sessionId_idx',
        'oauthAccessToken_userId_idx',
        'oauthAccessToken_refreshId_idx',
      ]),
    )
    expect(indexNames(oauthConsent)).toEqual(
      expect.arrayContaining(['oauthConsent_clientId_idx', 'oauthConsent_userId_idx', 'oauthConsent_referenceId_idx']),
    )
    expect(indexNames(uploadedAsset)).toEqual(
      expect.arrayContaining(['uploadedAsset_purpose_idx', 'uploadedAsset_createdByUserId_idx']),
    )
    expect(columnNames(siteSettings)).toEqual(['key', 'value', 'revision', 'updated_at'])
    expect(indexNames(customDomain)).toEqual(
      expect.arrayContaining([
        'customDomain_applicationId_idx',
        'customDomain_organizationId_idx',
        'customDomain_status_idx',
      ]),
    )
  })

  it('models webhook endpoint, delivery request, and delivery attempt persistence explicitly', () => {
    expect(columnNames(webhookEndpoint)).toEqual(
      expect.arrayContaining([
        'url',
        'events',
        'enabled',
        'organization_id',
        'signing_secret',
        'secret_prefix',
        'created_by_user_id',
      ]),
    )
    expect(indexNames(webhookEndpoint)).toEqual(
      expect.arrayContaining([
        'webhookEndpoint_enabled_idx',
        'webhookEndpoint_organizationId_idx',
        'webhookEndpoint_createdByUserId_idx',
      ]),
    )
    expect(foreignKeyReferences(webhookEndpoint)).toContainEqual({
      columns: ['created_by_user_id'],
      foreignColumns: ['id'],
      foreignTable: 'user',
      onDelete: 'set null',
    })
    expect(foreignKeyReferences(webhookEndpoint)).toContainEqual({
      columns: ['organization_id'],
      foreignColumns: ['id'],
      foreignTable: 'organization',
      onDelete: 'cascade',
    })

    expect(columnNames(webhookDeliveryRequest)).toEqual(
      expect.arrayContaining([
        'endpoint_id',
        'event',
        'status',
        'attempt_count',
        'request_body',
        'response_body',
        'next_attempt_at',
      ]),
    )
    expect(indexNames(webhookDeliveryRequest)).toEqual(
      expect.arrayContaining([
        'webhookDeliveryRequest_endpointId_idx',
        'webhookDeliveryRequest_status_idx',
        'webhookDeliveryRequest_createdAt_idx',
      ]),
    )
    expect(foreignKeyReferences(webhookDeliveryRequest)).toContainEqual({
      columns: ['endpoint_id'],
      foreignColumns: ['id'],
      foreignTable: 'webhook_endpoint',
      onDelete: 'cascade',
    })

    expect(columnNames(webhookDeliveryAttempt)).toEqual(
      expect.arrayContaining([
        'request_id',
        'sequence',
        'status',
        'http_status',
        'error',
        'response_body',
        'created_at',
        'completed_at',
      ]),
    )
    expect(indexNames(webhookDeliveryAttempt)).toEqual(
      expect.arrayContaining([
        'webhookDeliveryAttempt_requestSequence_uidx',
        'webhookDeliveryAttempt_requestId_idx',
        'webhookDeliveryAttempt_createdAt_idx',
      ]),
    )
    expect(foreignKeyReferences(webhookDeliveryAttempt)).toContainEqual({
      columns: ['request_id'],
      foreignColumns: ['id'],
      foreignTable: 'webhook_delivery_request',
      onDelete: 'cascade',
    })
  })

  it('defines relation graphs for auth, organization, application, and authorization records', () => {
    expect(relationKeys(userRelations)).toEqual(
      expect.arrayContaining([
        'sessions',
        'accounts',
        'passkeys',
        'twoFactors',
        'oauthClients',
        'oauthRefreshTokens',
        'oauthAccessTokens',
        'oauthConsents',
        'ownedApplications',
        'organizationMemberships',
      ]),
    )
    expect(relationKeys(twoFactorRelations)).toEqual(['user'])
    expect(relationKeys(passkeyRelations)).toEqual(['user'])
    expect(relationKeys(agentHostRelations)).toEqual(expect.arrayContaining(['user', 'agents', 'approvalRequests']))
    expect(relationKeys(agentRelations)).toEqual(expect.arrayContaining(['user', 'host', 'grants', 'approvalRequests']))
    expect(relationKeys(agentCapabilityGrantRelations)).toEqual(
      expect.arrayContaining(['agent', 'grantedByUser', 'deniedByUser']),
    )
    expect(relationKeys(approvalRequestRelations)).toEqual(expect.arrayContaining(['agent', 'host', 'user']))
    expect(relationKeys(sessionRelations)).toEqual(['user'])
    expect(relationKeys(accountRelations)).toEqual(['user'])
    expect(relationKeys(organizationRelations)).toEqual(
      expect.arrayContaining(['logoAsset', 'members', 'invitations', 'applications', 'teams']),
    )
    expect(relationKeys(organizationMemberRelations)).toEqual(expect.arrayContaining(['organization', 'user']))
    expect(relationKeys(organizationInvitationRelations)).toEqual(['organization', 'inviter'])
    expect(relationKeys(organizationTeamRelations)).toEqual(['organization', 'members'])
    expect(relationKeys(organizationTeamMemberRelations)).toEqual(['team', 'user'])
    expect(relationKeys(applicationRelations)).toEqual(
      expect.arrayContaining([
        'oauthClient',
        'ownerOrganization',
        'logoAsset',
        'clientSecrets',
        'consents',
        'scopeEntitlements',
      ]),
    )
    expect(relationKeys(apiResourceRelations)).toEqual(['ownerOrganization', 'scopeEntitlements'])
    expect(relationKeys(organizationRoleRelations)).toEqual(['organization'])
  })

  it('keeps timestamp update hooks executable for mutable records', () => {
    const updateValues = schemaTables
      .flatMap((table) => getTableConfig(table).columns)
      .filter((column) => column.onUpdateFn)
      .map((column) => column.onUpdateFn?.())

    expect(updateValues).toHaveLength(16)
    for (const value of updateValues) {
      expect(value).toBeInstanceOf(Date)
    }
  })
})

const schemaTables = [
  user,
  session,
  account,
  verification,
  jwks,
  twoFactor,
  passkey,
  oauthClient,
  oauthRefreshToken,
  oauthAccessToken,
  oauthConsent,
  agentHost,
  agent,
  agentCapabilityGrant,
  approvalRequest,
  uploadedAsset,
  organization,
  member,
  invitation,
  apiResource,
  organizationRole,
  application,
  applicationClientSecret,
  applicationClientMetadata,
  applicationConsent,
  identityProviderConnector,
  siteSettings,
  customDomain,
  webhookEndpoint,
  webhookDeliveryRequest,
]

function relationKeys(relationsObject: { config: (helpers: never) => Record<string, unknown> }) {
  return Object.keys(relationsObject.config(relationHelpers as never))
}

type RelationHelpers = {
  one: (table: unknown, config: unknown) => unknown
  many: (table: unknown) => unknown
}

const relationHelpers: RelationHelpers = {
  one: (table, config) => relationStub({ type: 'one', table, config }),
  many: (table) => relationStub({ type: 'many', table }),
}

function relationStub(value: unknown) {
  return {
    value,
    withFieldName: (fieldName: string) => ({ value, fieldName }),
  }
}