@happyvertical/smrt-profiles 0.54.2 → 0.54.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/dist/agent-profile.d.ts +2 -2
- package/dist/agent-profile.d.ts.map +1 -1
- package/dist/audit-trail.d.ts +24 -0
- package/dist/audit-trail.d.ts.map +1 -0
- package/dist/auth/index.d.ts +5 -5
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/magicLinkService.d.ts +2 -2
- package/dist/auth/magicLinkService.d.ts.map +1 -1
- package/dist/auth/nip05Handler.d.ts +1 -1
- package/dist/auth/nip05Handler.d.ts.map +1 -1
- package/dist/auth/oidcProvisioningPrimitives.d.ts +2 -2
- package/dist/auth/oidcProvisioningPrimitives.d.ts.map +1 -1
- package/dist/auth/resolveIdentity.d.ts +5 -5
- package/dist/auth/resolveIdentity.d.ts.map +1 -1
- package/dist/chunks/{ApiKey-BZmbOTnL.js → ApiKey-CVmlf3V6.js} +11 -3
- package/dist/chunks/ApiKey-CVmlf3V6.js.map +1 -0
- package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js → ApiKeyCollection-CiiDNFdD.js} +3 -3
- package/dist/chunks/{ApiKeyCollection-Bfb_nw81.js.map → ApiKeyCollection-CiiDNFdD.js.map} +1 -1
- package/dist/chunks/{AuditLogCollection-B1YonCAP.js → AuditLogCollection-WDHL-_AF.js} +30 -12
- package/dist/chunks/AuditLogCollection-WDHL-_AF.js.map +1 -0
- package/dist/chunks/{NostrIdentity-n70E0vck.js → NostrIdentity-AC8fAdxe.js} +12 -4
- package/dist/chunks/{NostrIdentity-n70E0vck.js.map → NostrIdentity-AC8fAdxe.js.map} +1 -1
- package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js → NostrIdentityCollection-CctlECpX.js} +2 -2
- package/dist/chunks/{NostrIdentityCollection-Ca74dkaL.js.map → NostrIdentityCollection-CctlECpX.js.map} +1 -1
- package/dist/chunks/{OidcIdentity-Cb1bxreM.js → OidcIdentity-BjRu3n1g.js} +11 -3
- package/dist/chunks/OidcIdentity-BjRu3n1g.js.map +1 -0
- package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js → OidcIdentityCollection-B4jYh36_.js} +3 -3
- package/dist/chunks/{OidcIdentityCollection-TV8VdK69.js.map → OidcIdentityCollection-B4jYh36_.js.map} +1 -1
- package/dist/chunks/{ProfileAssetCollection-B9hacUJa.js → ProfileAssetCollection-HeMtjBc0.js} +12 -3
- package/dist/chunks/ProfileAssetCollection-HeMtjBc0.js.map +1 -0
- package/dist/chunks/{ProfileCollection-DuJT7Mum.js → ProfileCollection-Bt6IJK49.js} +49 -25
- package/dist/chunks/ProfileCollection-Bt6IJK49.js.map +1 -0
- package/dist/chunks/{ProfileLinkCollection-4uNURz32.js → ProfileLinkCollection-u1hhzKTm.js} +11 -3
- package/dist/chunks/ProfileLinkCollection-u1hhzKTm.js.map +1 -0
- package/dist/chunks/{ProfileMetadataCollection-DQhbfEfa.js → ProfileMetadataCollection-BIYKy4Y3.js} +10 -2
- package/dist/chunks/ProfileMetadataCollection-BIYKy4Y3.js.map +1 -0
- package/dist/chunks/{ProfileMetafieldCollection-CoBuM_5G.js → ProfileMetafieldCollection-Buz7gzag.js} +10 -2
- package/dist/chunks/ProfileMetafieldCollection-Buz7gzag.js.map +1 -0
- package/dist/chunks/{ProfileRelationshipCollection-DUVgaIqf.js → ProfileRelationshipCollection-C4g_QLI4.js} +13 -5
- package/dist/chunks/ProfileRelationshipCollection-C4g_QLI4.js.map +1 -0
- package/dist/chunks/{ProfileRelationshipTermCollection-DtA9OM23.js → ProfileRelationshipTermCollection-C9J7mC7P.js} +10 -2
- package/dist/chunks/ProfileRelationshipTermCollection-C9J7mC7P.js.map +1 -0
- package/dist/chunks/{ProfileRelationshipType-BRiRka6t.js → ProfileRelationshipType-U7IwF6Wf.js} +10 -2
- package/dist/chunks/ProfileRelationshipType-U7IwF6Wf.js.map +1 -0
- package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js → ProfileRelationshipTypeCollection-_n22WqTb.js} +3 -3
- package/dist/chunks/{ProfileRelationshipTypeCollection-BdXwd7Kf.js.map → ProfileRelationshipTypeCollection-_n22WqTb.js.map} +1 -1
- package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js → oidcProvisioningPrimitives-CYood-2M.js} +14 -4
- package/dist/chunks/{oidcProvisioningPrimitives-D9OYu5-F.js.map → oidcProvisioningPrimitives-CYood-2M.js.map} +1 -1
- package/dist/chunks/{resolveIdentity-B-PK6RwU.js → resolveIdentity-CvGDegU6.js} +16 -16
- package/dist/chunks/{resolveIdentity-B-PK6RwU.js.map → resolveIdentity-CvGDegU6.js.map} +1 -1
- package/dist/collections/ApiKeyCollection.d.ts +2 -2
- package/dist/collections/ApiKeyCollection.d.ts.map +1 -1
- package/dist/collections/AuditLogCollection.d.ts +5 -3
- package/dist/collections/AuditLogCollection.d.ts.map +1 -1
- package/dist/collections/MagicLinkTokenCollection.d.ts +1 -1
- package/dist/collections/MagicLinkTokenCollection.d.ts.map +1 -1
- package/dist/collections/NostrIdentityCollection.d.ts +2 -2
- package/dist/collections/NostrIdentityCollection.d.ts.map +1 -1
- package/dist/collections/OidcIdentityCollection.d.ts +2 -2
- package/dist/collections/OidcIdentityCollection.d.ts.map +1 -1
- package/dist/collections/OidcProfileEmailReservationCollection.d.ts +1 -1
- package/dist/collections/OidcProfileEmailReservationCollection.d.ts.map +1 -1
- package/dist/collections/ProfileAssetCollection.d.ts +1 -1
- package/dist/collections/ProfileAssetCollection.d.ts.map +1 -1
- package/dist/collections/ProfileCollection.d.ts +1 -1
- package/dist/collections/ProfileCollection.d.ts.map +1 -1
- package/dist/collections/ProfileLinkCollection.d.ts +1 -1
- package/dist/collections/ProfileLinkCollection.d.ts.map +1 -1
- package/dist/collections/ProfileMetadataCollection.d.ts +1 -1
- package/dist/collections/ProfileMetadataCollection.d.ts.map +1 -1
- package/dist/collections/ProfileMetafieldCollection.d.ts +2 -2
- package/dist/collections/ProfileMetafieldCollection.d.ts.map +1 -1
- package/dist/collections/ProfileRelationshipCollection.d.ts +1 -1
- package/dist/collections/ProfileRelationshipCollection.d.ts.map +1 -1
- package/dist/collections/ProfileRelationshipTermCollection.d.ts +1 -1
- package/dist/collections/ProfileRelationshipTermCollection.d.ts.map +1 -1
- package/dist/collections/ProfileRelationshipTypeCollection.d.ts +1 -1
- package/dist/collections/ProfileRelationshipTypeCollection.d.ts.map +1 -1
- package/dist/collections/ProfileTypeCollection.d.ts +1 -1
- package/dist/collections/ProfileTypeCollection.d.ts.map +1 -1
- package/dist/collections/index.d.ts +15 -15
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/index.d.ts +51 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -24
- package/dist/index.js.map +1 -1
- package/dist/internal/oidc-provisioning.d.ts +1 -1
- package/dist/internal/oidc-provisioning.d.ts.map +1 -1
- package/dist/internal/oidc-provisioning.js +2 -2
- package/dist/manifest.json +126 -33
- package/dist/models/ApiKey.d.ts +1 -1
- package/dist/models/ApiKey.d.ts.map +1 -1
- package/dist/models/AuditLog.d.ts +10 -2
- package/dist/models/AuditLog.d.ts.map +1 -1
- package/dist/models/MagicLinkToken.d.ts +1 -1
- package/dist/models/MagicLinkToken.d.ts.map +1 -1
- package/dist/models/NostrIdentity.d.ts +1 -1
- package/dist/models/NostrIdentity.d.ts.map +1 -1
- package/dist/models/OidcIdentity.d.ts +1 -1
- package/dist/models/OidcIdentity.d.ts.map +1 -1
- package/dist/models/Profile.d.ts +10 -8
- package/dist/models/Profile.d.ts.map +1 -1
- package/dist/models/ProfileMetafield.d.ts +1 -1
- package/dist/models/ProfileMetafield.d.ts.map +1 -1
- package/dist/models/ProfileRelationship.d.ts +1 -1
- package/dist/models/ProfileRelationship.d.ts.map +1 -1
- package/dist/models/ProfileRelationshipType.d.ts +1 -1
- package/dist/models/ProfileRelationshipType.d.ts.map +1 -1
- package/dist/models/ProfileTypes.d.ts +1 -1
- package/dist/models/ProfileTypes.d.ts.map +1 -1
- package/dist/models/index.d.ts +15 -15
- package/dist/models/index.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +62 -366
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +4 -4
- package/package.json +12 -12
- package/dist/chunks/ApiKey-BZmbOTnL.js.map +0 -1
- package/dist/chunks/AuditLogCollection-B1YonCAP.js.map +0 -1
- package/dist/chunks/OidcIdentity-Cb1bxreM.js.map +0 -1
- package/dist/chunks/ProfileAssetCollection-B9hacUJa.js.map +0 -1
- package/dist/chunks/ProfileCollection-DuJT7Mum.js.map +0 -1
- package/dist/chunks/ProfileLinkCollection-4uNURz32.js.map +0 -1
- package/dist/chunks/ProfileMetadataCollection-DQhbfEfa.js.map +0 -1
- package/dist/chunks/ProfileMetafieldCollection-CoBuM_5G.js.map +0 -1
- package/dist/chunks/ProfileRelationshipCollection-DUVgaIqf.js.map +0 -1
- package/dist/chunks/ProfileRelationshipTermCollection-DtA9OM23.js.map +0 -1
- package/dist/chunks/ProfileRelationshipType-BRiRka6t.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/agent-profile.ts","../src/models/MagicLinkToken.ts","../src/collections/MagicLinkTokenCollection.ts","../src/auth/magicLinkService.ts","../src/auth/nip05Handler.ts"],"sourcesContent":["/**\n * Self-registers this package's build-time manifest before any @smrt() decorator\n * in the package fires. Fixes issue #1132: in consumer runtimes (tsx, SvelteKit\n * SSR, plain `vite dev`) the decorator's synchronous manifest lookup previously\n * missed because no step populated the global manifest cache — classes got\n * registered with zero fields and `save()` / `toJSON()` silently dropped every\n * declared property.\n *\n * Import this module as the first statement in `src/index.ts` so its top-level\n * side effect runs ahead of any class module's @smrt() decorator.\n *\n * Silent no-op in dev/test, where the vitest plugin already populates manifests\n * via a different path. Only needs to succeed in the published dist output.\n *\n * @see https://github.com/happyvertical/smrt/issues/1132\n */\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\n// During library builds, smrtPlugin replaces this entire module with generated\n// code that embeds the scanned manifest inline (#1506/#1507) — published dists\n// never resolve this URL, so downstream bundlers cannot break registration by\n// relocating the compiled module away from dist/manifest.json. The runtime\n// lookup below is the fallback for source-mode runs without that transform.\nObjectRegistry.registerPackageManifest(\n new URL('./manifest.json', import.meta.url),\n);\n","/**\n * Agent (bot) profile resolution (#2995).\n *\n * An automated agent that participates in a conversation is still an author,\n * and every authoring seam in the framework — `ChatMessage.senderProfileId`,\n * `ChatParticipant.profileId`, `ChatReaction.profileId`, a persona's\n * `actsAsProfileId` — is a `crossPackageRef` to a {@link Profile} and therefore\n * a native uuid column on PostgreSQL/DuckDB. A slug-style agent identifier\n * (`anytown_site_assistant`) is not a representable author there: it fails the\n * uuid cast (22P02) at the boundary that owns it.\n *\n * `Profile` already models this: the `bot` profile type is \"automated agents,\n * bots, and AI entities\". This module is the owning-package API that turns a\n * stable agent identifier into that Profile's uuid, so consumers never have to\n * mint bot profiles themselves and never have to weaken a uuid column to text.\n *\n * Identity is keyed on `(tenantId, slug = agentId, context =\n * {@link AGENT_PROFILE_CONTEXT})`. The reserved slug context keeps an agent\n * profile from ever colliding with an unrelated human/organization profile that\n * happens to share the slug, and matches the model's\n * `(tenant_id, slug, context, _meta_type)` unique key.\n *\n * @module\n */\n\nimport type { ProfileCollection } from './collections/ProfileCollection';\nimport { ProfileTypeCollection } from './collections/ProfileTypeCollection';\nimport type { Profile } from './models/Profile';\n\n/**\n * Reserved slug context for agent-owned profiles.\n *\n * Agent identifiers come from application configuration, not from the profile\n * namespace, so they are scoped into their own slug context rather than\n * competing with person/organization slugs.\n */\nexport const AGENT_PROFILE_CONTEXT = 'smrt:agent';\n\n/** Slug of the {@link ProfileType} agent profiles are classified under. */\nexport const AGENT_PROFILE_TYPE_SLUG = 'bot';\n\n/** Inputs for {@link resolveAgentProfile}. */\nexport interface ResolveAgentProfileParams {\n /** Stable agent identifier (e.g. `anytown_site_assistant`). */\n agentId: string;\n /** Owning tenant, or `null` for an untenanted agent. */\n tenantId?: string | null;\n /** Display name for a newly created profile. Defaults to `agentId`. */\n name?: string;\n}\n\n/**\n * Resolve — creating on first use — the {@link Profile} an agent authors as.\n *\n * The lookup is tenant-bound: an agent identifier resolves to a distinct\n * profile per tenant, so one tenant's assistant can never author into another\n * tenant's conversation. Resolution is idempotent; repeated calls for the same\n * `(tenantId, agentId)` return the same profile.\n *\n * @param profiles - Profile collection bound to the caller's database options.\n * @param params - Agent identity to resolve.\n * @returns The agent's profile, whose `id` is a real uuid.\n * @throws Error when `agentId` is empty.\n */\nexport async function resolveAgentProfile(\n profiles: ProfileCollection,\n params: ResolveAgentProfileParams,\n): Promise<Profile> {\n const agentId = params.agentId?.trim();\n if (!agentId) {\n throw new Error('resolveAgentProfile requires a non-empty agentId');\n }\n const tenantId = params.tenantId ?? null;\n const key = { slug: agentId, context: AGENT_PROFILE_CONTEXT, tenantId };\n\n // First use races (two simultaneous first turns for one agent) are resolved by\n // converging on the natural key rather than by whoever's INSERT won: each\n // attempt re-reads before and after writing, so a racer whose own write lost\n // to a revision conflict or to the `(tenant_id, slug, context)` upsert still\n // returns the surviving row instead of a dangling id. Two attempts suffice —\n // the loser of the first is a plain read on the second.\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n const existing = await profiles.get(key);\n if (existing) return existing;\n\n try {\n const profileTypes = await ProfileTypeCollection.create(profiles.options);\n const agentType = await profileTypes.getOrCreateBySlug(\n AGENT_PROFILE_TYPE_SLUG,\n {\n name: 'Bot',\n description: 'Automated agents, bots, and AI entities',\n },\n );\n\n const profile = await profiles.create({\n ...key,\n typeId: agentType.id as string,\n name: params.name?.trim() || agentId,\n });\n await profile.save();\n } catch (error) {\n lastError = error;\n }\n\n const settled = await profiles.get(key);\n if (settled) return settled;\n }\n\n throw new Error(\n `Could not resolve an agent profile for '${agentId}'${\n lastError instanceof Error ? `: ${lastError.message}` : ''\n }`,\n );\n}\n\n/**\n * Resolve an agent profile and return its uuid.\n *\n * Convenience wrapper for the common case — an authoring seam that needs the\n * id, not the row.\n *\n * @param profiles - Profile collection bound to the caller's database options.\n * @param params - Agent identity to resolve.\n * @returns The agent profile's uuid.\n */\nexport async function resolveAgentProfileId(\n profiles: ProfileCollection,\n params: ResolveAgentProfileParams,\n): Promise<string> {\n const profile = await resolveAgentProfile(profiles, params);\n const id = profile.id;\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n `Agent profile for '${params.agentId}' was persisted without an id`,\n );\n }\n return id;\n}\n","/**\n * MagicLinkToken - Temporary tokens for email verification\n *\n * Stores hashed magic link tokens with expiration. Tokens are single-use\n * and automatically invalidated after verification or expiration.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport {\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { NostrIdentity } from './NostrIdentity';\n\nexport interface MagicLinkTokenOptions extends SmrtObjectOptions {\n nostrIdentityId?: string;\n tokenHash?: string;\n email?: string;\n expiresAt?: Date;\n usedAt?: Date | null;\n requestedFromIp?: string;\n createdAt?: Date;\n}\n\nexport interface GenerateTokenResult {\n /** The plaintext token (only available at creation time) */\n token: string;\n /** The MagicLinkToken record */\n magicLinkToken: MagicLinkToken;\n}\n\n/** Default token expiration: 15 minutes */\nconst DEFAULT_EXPIRATION_MINUTES = 15;\n\n@smrt({\n tableName: 'magic_link_tokens',\n // Carries the login-token hash `verify()` looks up by. Never in the change\n // feed (#2937).\n sensitive: true,\n api: { exclude: ['*'] }, // No API access - internal only\n mcp: { exclude: ['*'] },\n cli: { include: ['list'] }, // Admin visibility only\n})\nexport class MagicLinkToken extends SmrtObject {\n /**\n * Link to the NostrIdentity this token is for\n */\n @foreignKey('NostrIdentity', { required: true })\n nostrIdentityId?: string;\n\n /**\n * SHA-256 hash of the token (never store plaintext).\n *\n * Indexed: `verify()` looks tokens up by this hash on every magic-link\n * click (#2364, epic #2382 finding A3).\n */\n @field({ indexed: true })\n tokenHash: string = '';\n\n /**\n * Email this token was sent to\n */\n email: string = '';\n\n /**\n * When this token expires\n */\n expiresAt: Date = new Date(\n Date.now() + DEFAULT_EXPIRATION_MINUTES * 60 * 1000,\n );\n\n /**\n * When this token was used (null = unused)\n */\n usedAt: Date | null = null;\n\n /**\n * IP address that requested the token (for rate limiting)\n */\n requestedFromIp: string = '';\n\n /**\n * When this token was created (for rate limiting)\n */\n createdAt: Date = new Date();\n\n constructor(options: MagicLinkTokenOptions = {}) {\n super(options);\n if (options.nostrIdentityId) this.nostrIdentityId = options.nostrIdentityId;\n if (options.tokenHash) this.tokenHash = options.tokenHash;\n if (options.email) this.email = options.email;\n if (options.expiresAt) this.expiresAt = options.expiresAt;\n if (options.usedAt !== undefined) this.usedAt = options.usedAt;\n if (options.requestedFromIp) this.requestedFromIp = options.requestedFromIp;\n if (options.createdAt) this.createdAt = options.createdAt;\n }\n\n /**\n * Hash a token using SHA-256\n */\n static hashToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n }\n\n /**\n * Generate a new magic link token\n * @param nostrIdentity - The identity this token is for\n * @param email - The email address to send to\n * @param options - Additional options\n */\n static async generate(\n nostrIdentity: NostrIdentity,\n email: string,\n options: {\n expiresInMinutes?: number;\n requestedFromIp?: string;\n db?: SmrtObjectOptions['db'];\n } = {},\n ): Promise<GenerateTokenResult> {\n // Generate 32 bytes of random data (256 bits of entropy)\n const tokenBytes = randomBytes(32);\n const token = tokenBytes.toString('base64url');\n const tokenHash = MagicLinkToken.hashToken(token);\n\n const expiresInMinutes =\n options.expiresInMinutes ?? DEFAULT_EXPIRATION_MINUTES;\n const expiresAt = new Date(Date.now() + expiresInMinutes * 60 * 1000);\n\n const magicLinkToken = new MagicLinkToken({\n db: options.db ?? nostrIdentity.options?.db,\n nostrIdentityId: nostrIdentity.id as string,\n tokenHash,\n email: email.toLowerCase(),\n expiresAt,\n requestedFromIp: options.requestedFromIp || '',\n });\n\n await magicLinkToken.initialize();\n await magicLinkToken.save();\n\n return { token, magicLinkToken };\n }\n\n /**\n * Verify a token and return the MagicLinkToken if valid\n * @param token - The plaintext token to verify\n * @param options - Database options\n * @returns The MagicLinkToken if valid, null otherwise\n */\n static async verify(\n token: string,\n options: SmrtObjectOptions = {},\n ): Promise<MagicLinkToken | null> {\n const tokenHash = MagicLinkToken.hashToken(token);\n\n const { MagicLinkTokenCollection } = await import(\n '../collections/MagicLinkTokenCollection'\n );\n const collection = await MagicLinkTokenCollection.create(options);\n\n const magicLinkToken = await collection.findOne({\n where: { tokenHash },\n });\n\n if (!magicLinkToken) {\n return null;\n }\n\n // Check if valid\n if (!magicLinkToken.isValid()) {\n return null;\n }\n\n return magicLinkToken;\n }\n\n /**\n * Check if this token is valid (not expired and not used)\n */\n isValid(): boolean {\n if (this.usedAt !== null) {\n return false;\n }\n if (new Date() > this.expiresAt) {\n return false;\n }\n return true;\n }\n\n /**\n * Check if this token has expired\n */\n isExpired(): boolean {\n return new Date() > this.expiresAt;\n }\n\n /**\n * Check if this token has been used\n */\n isUsed(): boolean {\n return this.usedAt !== null;\n }\n\n /**\n * Mark this token as used\n */\n async markUsed(): Promise<void> {\n this.usedAt = new Date();\n await this.save();\n }\n\n /**\n * Get the NostrIdentity this token is for\n */\n async getNostrIdentity(): Promise<NostrIdentity | null> {\n return (await this.getRelated('nostrIdentityId')) as NostrIdentity | null;\n }\n\n /**\n * Get time remaining until expiration in seconds\n */\n getTimeRemainingSeconds(): number {\n const now = new Date();\n const diff = this.expiresAt.getTime() - now.getTime();\n return Math.max(0, Math.floor(diff / 1000));\n }\n}\n","/**\n * MagicLinkTokenCollection - Collection for managing magic link tokens\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { MagicLinkToken } from '../models/MagicLinkToken';\n\nexport class MagicLinkTokenCollection extends SmrtCollection<MagicLinkToken> {\n static readonly _itemClass = MagicLinkToken;\n\n /**\n * Find token by hash\n */\n async findByTokenHash(tokenHash: string): Promise<MagicLinkToken | null> {\n return await this.findOne({\n where: { tokenHash },\n });\n }\n\n /**\n * Find active (non-expired, non-used) tokens for an email\n */\n async findActiveForEmail(email: string): Promise<MagicLinkToken[]> {\n const tokens = await this.list({\n where: { email: email.toLowerCase() },\n });\n return tokens.filter((token) => token.isValid());\n }\n\n /**\n * Find tokens for a NostrIdentity\n */\n async findByIdentity(nostrIdentityId: string): Promise<MagicLinkToken[]> {\n return await this.list({\n where: { nostrIdentityId },\n });\n }\n\n /**\n * Count tokens created for an email within a time window (for rate limiting)\n * @param email - Email address\n * @param withinMinutes - Time window in minutes\n */\n async countRecentByEmail(\n email: string,\n withinMinutes: number,\n ): Promise<number> {\n const cutoff = new Date(Date.now() - withinMinutes * 60 * 1000);\n const tokens = await this.list({\n where: { email: email.toLowerCase() },\n });\n\n // Filter tokens created after cutoff\n // Note: We use createdAt from SmrtObject base\n return tokens.filter((token) => {\n const createdAt = token.createdAt;\n return createdAt && new Date(createdAt) > cutoff;\n }).length;\n }\n\n /**\n * Count tokens created from an IP within a time window (for rate limiting)\n * @param ip - IP address\n * @param withinMinutes - Time window in minutes\n */\n async countRecentByIp(ip: string, withinMinutes: number): Promise<number> {\n const cutoff = new Date(Date.now() - withinMinutes * 60 * 1000);\n const tokens = await this.list({\n where: { requestedFromIp: ip },\n });\n\n // Filter tokens created after cutoff\n return tokens.filter((token) => {\n const createdAt = token.createdAt;\n return createdAt && new Date(createdAt) > cutoff;\n }).length;\n }\n\n /**\n * Verify a token and return it if valid\n */\n async verify(token: string): Promise<MagicLinkToken | null> {\n const tokenHash = MagicLinkToken.hashToken(token);\n const magicLinkToken = await this.findByTokenHash(tokenHash);\n\n if (!magicLinkToken) {\n return null;\n }\n\n if (!magicLinkToken.isValid()) {\n return null;\n }\n\n return magicLinkToken;\n }\n\n /**\n * Clean up expired tokens by deleting them\n * @returns Number of tokens deleted\n */\n async cleanupExpired(): Promise<number> {\n const now = new Date();\n const allTokens = await this.list({});\n let deleted = 0;\n\n for (const token of allTokens) {\n if (token.isExpired() || token.isUsed()) {\n await token.delete();\n deleted++;\n }\n }\n\n return deleted;\n }\n\n /**\n * Revoke all tokens for a NostrIdentity (e.g., when identity is deleted)\n */\n async revokeForIdentity(nostrIdentityId: string): Promise<number> {\n const tokens = await this.findByIdentity(nostrIdentityId);\n let revoked = 0;\n\n for (const token of tokens) {\n if (!token.isUsed()) {\n await token.markUsed(); // Mark as used to invalidate\n revoked++;\n }\n }\n\n return revoked;\n }\n\n /**\n * Check if rate limit is exceeded for email\n * @param email - Email address\n * @param maxPerHour - Maximum tokens allowed per hour (default: 5)\n */\n async isRateLimitedByEmail(\n email: string,\n maxPerHour: number = 5,\n ): Promise<boolean> {\n const count = await this.countRecentByEmail(email, 60);\n return count >= maxPerHour;\n }\n\n /**\n * Check if rate limit is exceeded for IP\n * @param ip - IP address\n * @param maxPerHour - Maximum tokens allowed per hour (default: 10)\n */\n async isRateLimitedByIp(\n ip: string,\n maxPerHour: number = 10,\n ): Promise<boolean> {\n const count = await this.countRecentByIp(ip, 60);\n return count >= maxPerHour;\n }\n}\n","/**\n * Magic Link Service\n *\n * Handles the magic link authentication flow including:\n * - Token generation and storage\n * - Email sending (via callback)\n * - Token verification\n * - Rate limiting checks\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { MagicLinkTokenCollection } from '../collections/MagicLinkTokenCollection';\nimport { NostrIdentityCollection } from '../collections/NostrIdentityCollection';\nimport { MagicLinkToken } from '../models/MagicLinkToken';\nimport type { NostrIdentity } from '../models/NostrIdentity';\nimport type { Profile } from '../models/Profile';\nimport { encryptPrivkey, generateNostrKeypair } from './nostrCrypto';\n\nexport interface MagicLinkConfig {\n /** Base URL for magic links (e.g., \"https://example.com\") */\n baseUrl: string;\n /** Path for verification endpoint (default: \"/auth/verify\") */\n verifyPath?: string;\n /** Token expiration in minutes (default: 15) */\n expiresInMinutes?: number;\n /** Maximum tokens per email per hour (default: 5) */\n maxTokensPerEmailPerHour?: number;\n /** Maximum tokens per IP per hour (default: 10) */\n maxTokensPerIpPerHour?: number;\n /** Server master secret for encryption */\n masterSecret: string;\n /** Callback to send the email */\n sendEmail: (to: string, magicLink: string) => Promise<void>;\n /** Database options */\n db: SmrtObjectOptions['db'];\n}\n\nexport interface InitiateResult {\n success: boolean;\n /** The Nostr identity (existing or new) */\n nostrIdentity?: NostrIdentity;\n /** The profile (existing or new) */\n profile?: Profile;\n /** True if a new profile was created */\n created: boolean;\n /** Error message if success is false */\n error?: string;\n /** Error code for programmatic handling */\n errorCode?: 'RATE_LIMITED_EMAIL' | 'RATE_LIMITED_IP' | 'EMAIL_SEND_FAILED';\n}\n\nexport interface VerifyResult {\n success: boolean;\n /** The profile */\n profile?: Profile;\n /** The Nostr identity */\n nostrIdentity?: NostrIdentity;\n /** The decrypted keypair (only on success) */\n keypair?: {\n pubkey: string;\n privkey: string;\n npub: string;\n nsec: string;\n };\n /** Error message if success is false */\n error?: string;\n /** Error code for programmatic handling */\n errorCode?: 'INVALID_TOKEN' | 'EXPIRED_TOKEN' | 'USED_TOKEN' | 'NOT_FOUND';\n}\n\nexport interface MagicLinkService {\n /**\n * Initiate magic link flow - generates token and sends email\n */\n initiate(\n email: string,\n options?: {\n requestedFromIp?: string;\n nip05Username?: string;\n },\n ): Promise<InitiateResult>;\n\n /**\n * Verify a magic link token and return decrypted keypair\n */\n verify(token: string): Promise<VerifyResult>;\n}\n\n/**\n * Create a magic link service instance\n */\nexport function createMagicLinkService(\n config: MagicLinkConfig,\n): MagicLinkService {\n const {\n baseUrl,\n verifyPath = '/auth/verify',\n expiresInMinutes = 15,\n maxTokensPerEmailPerHour = 5,\n maxTokensPerIpPerHour = 10,\n masterSecret,\n sendEmail,\n db,\n } = config;\n\n return {\n async initiate(\n email: string,\n options: {\n requestedFromIp?: string;\n nip05Username?: string;\n } = {},\n ): Promise<InitiateResult> {\n const normalizedEmail = email.toLowerCase().trim();\n const { requestedFromIp, nip05Username } = options;\n\n // Create collections\n const identityCollection = await NostrIdentityCollection.create({ db });\n const tokenCollection = await MagicLinkTokenCollection.create({ db });\n\n // Rate limiting checks\n if (\n await tokenCollection.isRateLimitedByEmail(\n normalizedEmail,\n maxTokensPerEmailPerHour,\n )\n ) {\n return {\n success: false,\n created: false,\n error: 'Too many requests for this email. Please try again later.',\n errorCode: 'RATE_LIMITED_EMAIL',\n };\n }\n\n if (\n requestedFromIp &&\n (await tokenCollection.isRateLimitedByIp(\n requestedFromIp,\n maxTokensPerIpPerHour,\n ))\n ) {\n return {\n success: false,\n created: false,\n error: 'Too many requests from this IP. Please try again later.',\n errorCode: 'RATE_LIMITED_IP',\n };\n }\n\n // Check if identity exists\n let nostrIdentity = await identityCollection.findByEmail(normalizedEmail);\n let profile: Profile | null = null;\n let created = false;\n\n if (!nostrIdentity) {\n // Create new identity and profile\n const { Person } = await import('../models/ProfileTypes');\n const { ProfileTypeCollection } = await import(\n '../collections/ProfileTypeCollection'\n );\n\n // Profile.typeId is a required FK, so resolve (or seed) the canonical\n // 'person' type before creating the profile — otherwise `.save()`\n // fails required-field validation. Mirrors createProfileFromNostr /\n // createProfileFromOidc in resolveIdentity.ts.\n const typeCollection = await ProfileTypeCollection.create({ db });\n let personType = await typeCollection.getBySlug('person');\n if (!personType) {\n const { ProfileType } = await import('../models/ProfileType');\n personType = new ProfileType({\n db,\n slug: 'person',\n name: 'Person',\n description: 'Individual person profile',\n });\n await personType.initialize();\n await personType.save();\n }\n\n // Create a new profile for this user (Person is an STI subclass of Profile)\n profile = new Person({\n db,\n typeId: personType.id as string,\n email: normalizedEmail,\n name: normalizedEmail.split('@')[0], // Default name from email\n });\n await profile.initialize();\n await profile.save();\n\n // Generate keypair and encrypt\n const keypair = generateNostrKeypair();\n const encrypted = encryptPrivkey(keypair.privkey, masterSecret);\n\n // Create Nostr identity\n const { NostrIdentity: NostrIdentityClass } = await import(\n '../models/NostrIdentity'\n );\n nostrIdentity = new NostrIdentityClass({\n db,\n profileId: profile.id!,\n pubkey: keypair.pubkey,\n encryptedPrivkey: encrypted.ciphertext,\n encryptionIv: encrypted.iv,\n encryptionTag: encrypted.tag,\n email: normalizedEmail,\n nip05Username:\n nip05Username?.toLowerCase() || normalizedEmail.split('@')[0],\n });\n await nostrIdentity.initialize();\n await nostrIdentity.save();\n\n created = true;\n } else {\n profile = await nostrIdentity.getProfile();\n }\n\n // Generate magic link token\n const { token } = await MagicLinkToken.generate(\n nostrIdentity,\n normalizedEmail,\n {\n expiresInMinutes,\n requestedFromIp,\n db,\n },\n );\n\n // Build magic link URL\n const magicLink = `${baseUrl}${verifyPath}?token=${encodeURIComponent(token)}`;\n\n // Send email\n try {\n await sendEmail(normalizedEmail, magicLink);\n } catch (emailError) {\n return {\n success: false,\n created,\n nostrIdentity,\n profile: profile || undefined,\n error: 'Failed to send email. Please try again.',\n errorCode: 'EMAIL_SEND_FAILED',\n };\n }\n\n return {\n success: true,\n created,\n nostrIdentity,\n profile: profile || undefined,\n };\n },\n\n async verify(token: string): Promise<VerifyResult> {\n // Verify token\n const magicLinkToken = await MagicLinkToken.verify(token, { db });\n\n if (!magicLinkToken) {\n // Try to get more specific error\n const tokenHash = MagicLinkToken.hashToken(token);\n const tokenCollection = await MagicLinkTokenCollection.create({ db });\n const existingToken = await tokenCollection.findByTokenHash(tokenHash);\n\n if (!existingToken) {\n return {\n success: false,\n error: 'Invalid or expired token.',\n errorCode: 'NOT_FOUND',\n };\n }\n\n if (existingToken.isUsed()) {\n return {\n success: false,\n error: 'This link has already been used.',\n errorCode: 'USED_TOKEN',\n };\n }\n\n if (existingToken.isExpired()) {\n return {\n success: false,\n error: 'This link has expired. Please request a new one.',\n errorCode: 'EXPIRED_TOKEN',\n };\n }\n\n return {\n success: false,\n error: 'Invalid token.',\n errorCode: 'INVALID_TOKEN',\n };\n }\n\n // Mark token as used\n await magicLinkToken.markUsed();\n\n // Get the Nostr identity\n const nostrIdentity = await magicLinkToken.getNostrIdentity();\n if (!nostrIdentity) {\n return {\n success: false,\n error: 'Identity not found.',\n errorCode: 'NOT_FOUND',\n };\n }\n\n // Mark identity as verified\n await nostrIdentity.markVerified();\n\n // Get profile\n const profile = await nostrIdentity.getProfile();\n\n // Decrypt keypair\n const keypair = nostrIdentity.getKeypair(masterSecret);\n\n return {\n success: true,\n profile: profile || undefined,\n nostrIdentity,\n keypair,\n };\n },\n };\n}\n","/**\n * NIP-05 Handler\n *\n * Provides a helper for serving the /.well-known/nostr.json endpoint\n * for NIP-05 identity verification.\n *\n * @see https://github.com/nostr-protocol/nips/blob/master/05.md\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n type Nip05Response,\n NostrIdentityCollection,\n} from '../collections/NostrIdentityCollection';\n\nexport interface Nip05HandlerConfig {\n /** Database options */\n db: SmrtObjectOptions['db'];\n /** Optional: Additional relays to include for all users */\n defaultRelays?: string[];\n /** Optional: Cache TTL in seconds (default: 300 = 5 minutes) */\n cacheTtlSeconds?: number;\n}\n\nexport interface Nip05Request {\n /** The 'name' query parameter from the request */\n name?: string | null;\n}\n\nexport interface Nip05HandlerResult {\n /** The NIP-05 response body */\n body: Nip05Response;\n /** Suggested headers for the response */\n headers: Record<string, string>;\n /** HTTP status code */\n status: number;\n}\n\n/**\n * Create a NIP-05 handler\n *\n * @example\n * // SvelteKit\n * import { createNip05Handler } from '@happyvertical/smrt-profiles';\n *\n * const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });\n *\n * export async function GET({ url }) {\n * const result = await handler({ name: url.searchParams.get('name') });\n * return new Response(JSON.stringify(result.body), {\n * status: result.status,\n * headers: result.headers,\n * });\n * }\n *\n * @example\n * // Express\n * import { createNip05Handler } from '@happyvertical/smrt-profiles';\n *\n * const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });\n *\n * app.get('/.well-known/nostr.json', async (req, res) => {\n * const result = await handler({ name: req.query.name });\n * res.status(result.status).set(result.headers).json(result.body);\n * });\n */\nexport function createNip05Handler(config: Nip05HandlerConfig) {\n const { db, defaultRelays = [], cacheTtlSeconds = 300 } = config;\n\n return async function handleNip05Request(\n request: Nip05Request,\n ): Promise<Nip05HandlerResult> {\n const { name } = request;\n\n const collection = await NostrIdentityCollection.create({ db });\n const response = await collection.getNip05Response(name || undefined);\n\n // Add default relays if configured\n if (defaultRelays.length > 0 && Object.keys(response.names).length > 0) {\n response.relays = {};\n for (const pubkey of Object.values(response.names)) {\n response.relays[pubkey] = defaultRelays;\n }\n }\n\n // If specific name requested but not found, return empty names\n if (name && Object.keys(response.names).length === 0) {\n return {\n body: { names: {} },\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': `public, max-age=${cacheTtlSeconds}`,\n },\n status: 200, // NIP-05 spec says return 200 with empty names, not 404\n };\n }\n\n return {\n body: response,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': `public, max-age=${cacheTtlSeconds}`,\n },\n status: 200,\n };\n };\n}\n\n/**\n * Validate a NIP-05 identifier format\n * @param identifier - The identifier to validate (e.g., \"alice@example.com\")\n */\nexport function isValidNip05Identifier(identifier: string): boolean {\n // NIP-05 format: <local-part>@<domain>\n const parts = identifier.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [localPart, domain] = parts;\n\n // Local part: alphanumeric, _, -\n if (!/^[a-z0-9_-]+$/i.test(localPart)) {\n return false;\n }\n\n // Domain: basic domain validation\n if (!/^[a-z0-9.-]+\\.[a-z]{2,}$/i.test(domain)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Parse a NIP-05 identifier into its parts\n * @param identifier - The identifier to parse (e.g., \"alice@example.com\")\n */\nexport function parseNip05Identifier(identifier: string): {\n localPart: string;\n domain: string;\n} | null {\n if (!isValidNip05Identifier(identifier)) {\n return null;\n }\n\n const [localPart, domain] = identifier.split('@');\n return { localPart, domain };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/agent-profile.ts","../src/audit-trail.ts","../src/models/MagicLinkToken.ts","../src/collections/MagicLinkTokenCollection.ts","../src/auth/magicLinkService.ts","../src/auth/nip05Handler.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"packageVersion\\\":\\\"0.54.4\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-profiles:ApiKeyCollection\\\":{\\\"name\\\":\\\"apikeycollection\\\",\\\"className\\\":\\\"ApiKeyCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ApiKeyCollection\\\",\\\"collection\\\":\\\"apikeys\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ApiKeyCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByProfile\\\":{\\\"name\\\":\\\"findByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActiveByProfile\\\":{\\\"name\\\":\\\"findActiveByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByHash\\\":{\\\"name\\\":\\\"findByHash\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"keyHash\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ApiKey | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"verify\\\":{\\\"name\\\":\\\"verify\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ApiKey | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateForProfile\\\":{\\\"name\\\":\\\"generateForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"revokeAllForProfile\\\":{\\\"name\\\":\\\"revokeAllForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"revokeByPrefix\\\":{\\\"name\\\":\\\"revokeByPrefix\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"keyPrefix\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"cleanupExpired\\\":{\\\"name\\\":\\\"cleanupExpired\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"api_keys\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ApiKey\\\",\\\"exportName\\\":\\\"ApiKeyCollection\\\",\\\"collectionExportName\\\":\\\"ApiKeyCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"api_keys\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"api_keys\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"key_hash\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"key_prefix\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"scopes\\\\\\\" JSON DEFAULT '[]',\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"expires_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"revoked_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"key_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"key_prefix\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scopes\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":[]},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"expires_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"revoked_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"api_keys_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"api_keys_key_hash_idx\\\",\\\"columns\\\":[\\\"key_hash\\\"]},{\\\"name\\\":\\\"api_keys_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"api_keys_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"9b0d49e8\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:AuditLogCollection\\\":{\\\"name\\\":\\\"auditlogcollection\\\",\\\"className\\\":\\\"AuditLogCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:AuditLogCollection\\\",\\\"collection\\\":\\\"auditlogs\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/AuditLogCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByProfile\\\":{\\\"name\\\":\\\"findByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByResource\\\":{\\\"name\\\":\\\"findByResource\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"resourceType\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"resourceId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByAction\\\":{\\\"name\\\":\\\"findByAction\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"action\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBySource\\\":{\\\"name\\\":\\\"findBySource\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"source\\\",\\\"type\\\":\\\"AuditSource\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findOnBehalfOf\\\":{\\\"name\\\":\\\"findOnBehalfOf\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"record\\\":{\\\"name\\\":\\\"record\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"Profile\\\",\\\"string\\\",\\\"AuditSource\\\",\\\"Record<string, unknown>\\\",\\\"Profile | null\\\",\\\"Record<string, AuditChange>\\\"]}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRecentActivity\\\":{\\\"name\\\":\\\"getRecentActivity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getResourceTimeline\\\":{\\\"name\\\":\\\"getResourceTimeline\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"resourceType\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"resourceId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"audit_logs\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"AuditLog\\\",\\\"exportName\\\":\\\"AuditLogCollection\\\",\\\"collectionExportName\\\":\\\"AuditLogCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"audit_logs\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"audit_logs\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"action\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"reason\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"changes\\\\\\\" JSON DEFAULT '{}',\\\\n \\\\\\\"resource_type\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"resource_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"occurred_at\\\\\\\" TIMESTAMP DEFAULT current_timestamp,\\\\n \\\\\\\"source\\\\\\\" TEXT DEFAULT 'web',\\\\n \\\\\\\"metadata\\\\\\\" JSON DEFAULT '{}',\\\\n \\\\\\\"on_behalf_of_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"action\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"changes\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":{}},\\\"resource_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"resource_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"occurred_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"current_timestamp\\\"},\\\"source\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"web\\\"},\\\"metadata\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":{}},\\\"on_behalf_of_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}}},\\\"indexes\\\":[{\\\"name\\\":\\\"audit_logs_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"audit_logs_resource_type_idx\\\",\\\"columns\\\":[\\\"resource_type\\\"]},{\\\"name\\\":\\\"audit_logs_resource_id_idx\\\",\\\"columns\\\":[\\\"resource_id\\\"]},{\\\"name\\\":\\\"audit_logs_occurred_at_idx\\\",\\\"columns\\\":[\\\"occurred_at\\\"]},{\\\"name\\\":\\\"audit_logs_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"audit_logs_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"audit_logs_on_behalf_of_id_idx\\\",\\\"columns\\\":[\\\"on_behalf_of_id\\\"]}],\\\"version\\\":\\\"769bd855\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:MagicLinkTokenCollection\\\":{\\\"name\\\":\\\"magiclinktokencollection\\\",\\\"className\\\":\\\"MagicLinkTokenCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:MagicLinkTokenCollection\\\",\\\"collection\\\":\\\"magiclinktokens\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/MagicLinkTokenCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByTokenHash\\\":{\\\"name\\\":\\\"findByTokenHash\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tokenHash\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<MagicLinkToken | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findActiveForEmail\\\":{\\\"name\\\":\\\"findActiveForEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<MagicLinkToken[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByIdentity\\\":{\\\"name\\\":\\\"findByIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrIdentityId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<MagicLinkToken[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countRecentByEmail\\\":{\\\"name\\\":\\\"countRecentByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"withinMinutes\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"countRecentByIp\\\":{\\\"name\\\":\\\"countRecentByIp\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"ip\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"withinMinutes\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"verify\\\":{\\\"name\\\":\\\"verify\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"token\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<MagicLinkToken | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"cleanupExpired\\\":{\\\"name\\\":\\\"cleanupExpired\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"revokeForIdentity\\\":{\\\"name\\\":\\\"revokeForIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrIdentityId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<number>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isRateLimitedByEmail\\\":{\\\"name\\\":\\\"isRateLimitedByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"maxPerHour\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isRateLimitedByIp\\\":{\\\"name\\\":\\\"isRateLimitedByIp\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"ip\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"maxPerHour\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"magic_link_tokens\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"MagicLinkToken\\\",\\\"exportName\\\":\\\"MagicLinkTokenCollection\\\",\\\"collectionExportName\\\":\\\"MagicLinkTokenCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"magic_link_tokens\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"magic_link_tokens\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"nostr_identity_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"token_hash\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"email\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"expires_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"requested_from_ip\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"nostr_identity_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"nostr_identities\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"token_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"expires_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"requested_from_ip\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"magic_link_tokens_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"magic_link_tokens_token_hash_idx\\\",\\\"columns\\\":[\\\"token_hash\\\"]},{\\\"name\\\":\\\"magic_link_tokens_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"magic_link_tokens_nostr_identity_id_idx\\\",\\\"columns\\\":[\\\"nostr_identity_id\\\"]}],\\\"version\\\":\\\"d60748fe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:NostrIdentityCollection\\\":{\\\"name\\\":\\\"nostridentitycollection\\\",\\\"className\\\":\\\"NostrIdentityCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:NostrIdentityCollection\\\",\\\"collection\\\":\\\"nostridentities\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/NostrIdentityCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByProfile\\\":{\\\"name\\\":\\\"findByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<NostrIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByPubkey\\\":{\\\"name\\\":\\\"findByPubkey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByEmail\\\":{\\\"name\\\":\\\"findByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByNip05\\\":{\\\"name\\\":\\\"findByNip05\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"username\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"createForProfile\\\":{\\\"name\\\":\\\"createForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"masterSecret\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"nip05Username\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkToProfile\\\":{\\\"name\\\":\\\"linkToProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"nostrData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"unlinkFromProfile\\\":{\\\"name\\\":\\\"unlinkFromProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNip05Response\\\":{\\\"name\\\":\\\"getNip05Response\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"username\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Nip05Response>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isNip05Available\\\":{\\\"name\\\":\\\"isNip05Available\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"username\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"updateNip05Username\\\":{\\\"name\\\":\\\"updateNip05Username\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"identity\\\",\\\"type\\\":\\\"NostrIdentity\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"newUsername\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"nostr_identities\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"NostrIdentity\\\",\\\"exportName\\\":\\\"NostrIdentityCollection\\\",\\\"collectionExportName\\\":\\\"NostrIdentityCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"nostr_identities\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"nostr_identities\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"pubkey\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encrypted_privkey\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encryption_iv\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encryption_tag\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"email\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"nip05_username\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"verified_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"pubkey\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encrypted_privkey\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryption_iv\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryption_tag\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"nip05_username\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"verified_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"nostr_identities_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"nostr_identities_pubkey_idx\\\",\\\"columns\\\":[\\\"pubkey\\\"]},{\\\"name\\\":\\\"nostr_identities_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"nostr_identities_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"92eda375\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:OidcIdentityCollection\\\":{\\\"name\\\":\\\"oidcidentitycollection\\\",\\\"className\\\":\\\"OidcIdentityCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:OidcIdentityCollection\\\",\\\"collection\\\":\\\"oidcidentities\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/OidcIdentityCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByProfile\\\":{\\\"name\\\":\\\"findByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBySubject\\\":{\\\"name\\\":\\\"findBySubject\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"issuer\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"subject\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<OidcIdentity | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByProvider\\\":{\\\"name\\\":\\\"findByProvider\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"provider\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkToProfile\\\":{\\\"name\\\":\\\"linkToProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"unlinkFromProfile\\\":{\\\"name\\\":\\\"unlinkFromProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"issuer\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"subject\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"oidc_identities\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"OidcIdentity\\\",\\\"exportName\\\":\\\"OidcIdentityCollection\\\",\\\"collectionExportName\\\":\\\"OidcIdentityCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"oidc_identities\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"oidc_identities\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"provider\\\\\\\" TEXT,\\\\n \\\\\\\"issuer\\\\\\\" TEXT,\\\\n \\\\\\\"subject\\\\\\\" TEXT,\\\\n \\\\\\\"identity_key\\\\\\\" TEXT UNIQUE,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"provider\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"issuer\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"subject\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"identity_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":true},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"oidc_identities_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"oidc_identities_issuer_idx\\\",\\\"columns\\\":[\\\"issuer\\\"]},{\\\"name\\\":\\\"oidc_identities_subject_idx\\\",\\\"columns\\\":[\\\"subject\\\"]},{\\\"name\\\":\\\"oidc_identities_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"oidc_identities_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"925387ea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:OidcProfileEmailReservationCollection\\\":{\\\"name\\\":\\\"oidcprofileemailreservationcollection\\\",\\\"className\\\":\\\"OidcProfileEmailReservationCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:OidcProfileEmailReservationCollection\\\",\\\"collection\\\":\\\"oidcprofileemailreservations\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/OidcProfileEmailReservationCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"oidc_profile_email_reservations\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"OidcProfileEmailReservation\\\",\\\"exportName\\\":\\\"OidcProfileEmailReservationCollection\\\",\\\"collectionExportName\\\":\\\"OidcProfileEmailReservationCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"oidc_profile_email_reservations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"oidc_profile_email_reservations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL UNIQUE,\\\\n \\\\\\\"email_key\\\\\\\" TEXT NOT NULL UNIQUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":true,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"oidc_profile_email_reservations_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"oidc_profile_email_reservations_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"01586e67\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileAssetCollection\\\":{\\\"name\\\":\\\"profileassetcollection\\\",\\\"className\\\":\\\"ProfileAssetCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileAssetCollection\\\",\\\"collection\\\":\\\"profileassets\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileAssetCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"byRight\\\":{\\\"name\\\":\\\"byRight\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"rightId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"opts\\\",\\\"type\\\":\\\"JunctionFilterOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<TItem[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"byLeft\\\":{\\\"name\\\":\\\"byLeft\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"leftId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"opts\\\",\\\"type\\\":\\\"JunctionFilterOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<TItem[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"attach\\\":{\\\"name\\\":\\\"attach\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"leftId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"rightId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"opts\\\",\\\"type\\\":\\\"JunctionAttachOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<TItem>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"detach\\\":{\\\"name\\\":\\\"detach\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"leftId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"rightId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"opts\\\",\\\"type\\\":\\\"JunctionFilterOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setLinks\\\":{\\\"name\\\":\\\"setLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"leftId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"rightIds\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"opts\\\",\\\"type\\\":\\\"JunctionAttachOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false,\\\"tableName\\\":\\\"profile_assets\\\"},\\\"extends\\\":\\\"SmrtJunction\\\",\\\"extendsTypeArg\\\":\\\"ProfileAsset\\\",\\\"exportName\\\":\\\"ProfileAssetCollection\\\",\\\"collectionExportName\\\":\\\"ProfileAssetCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_assets\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_assets\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"asset_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"relationship\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"sort_order\\\\\\\" INTEGER NOT NULL DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"relationship\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"sort_order\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_assets_profile_id_asset_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\",\\\"asset_id\\\",\\\"relationship\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_assets_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"profile_assets_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_assets_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"d0d7c2a2\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileCollection\\\":{\\\"name\\\":\\\"profilecollection\\\",\\\"className\\\":\\\"ProfileCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileCollection\\\",\\\"collection\\\":\\\"profiles\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"findByEmail\\\":{\\\"name\\\":\\\"findByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findUniqueGlobalPersonByEmail\\\":{\\\"name\\\":\\\"findUniqueGlobalPersonByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"requireCanonicalGlobalPerson\\\":{\\\"name\\\":\\\"requireCanonicalGlobalPerson\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"reserveCanonicalIdentityEmail\\\":{\\\"name\\\":\\\"reserveCanonicalIdentityEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"typeSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"batchGetMetadata\\\":{\\\"name\\\":\\\"batchGetMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileIds\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Map<string, Record<string, string>>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"batchUpdateMetadata\\\":{\\\"name\\\":\\\"batchUpdateMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"updates\\\",\\\"type\\\":\\\"Array<object>\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"Record<string, unknown>\\\"]}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findRelated\\\":{\\\"name\\\":\\\"findRelated\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelationshipNetwork\\\":{\\\"name\\\":\\\"getRelationshipNetwork\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"number\\\"]}],\\\"returnType\\\":\\\"Promise<Map<string, number>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByTenant\\\":{\\\"name\\\":\\\"findByTenant\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findGlobal\\\":{\\\"name\\\":\\\"findGlobal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findWithGlobals\\\":{\\\"name\\\":\\\"findWithGlobals\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"Profile\\\",\\\"exportName\\\":\\\"ProfileCollection\\\",\\\"collectionExportName\\\":\\\"ProfileCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profiles\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profiles\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"email_key\\\\\\\" TEXT,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"is_public\\\\\\\" BOOLEAN DEFAULT FALSE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"is_public\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profiles_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profiles_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profiles_email_key_idx\\\",\\\"columns\\\":[\\\"email_key\\\"]},{\\\"name\\\":\\\"profiles_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profiles_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]}],\\\"version\\\":\\\"f4a7b632\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileLinkCollection\\\":{\\\"name\\\":\\\"profilelinkcollection\\\",\\\"className\\\":\\\"ProfileLinkCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileLinkCollection\\\",\\\"collection\\\":\\\"profilelinks\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileLinkCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"listForProfile\\\":{\\\"name\\\":\\\"listForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"replaceForProfile\\\":{\\\"name\\\":\\\"replaceForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"links\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"reorder\\\":{\\\"name\\\":\\\"reorder\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"linkIds\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"profile_links\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileLink\\\",\\\"exportName\\\":\\\"ProfileLinkCollection\\\",\\\"collectionExportName\\\":\\\"ProfileLinkCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_links\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_links\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"platform\\\\\\\" TEXT NOT NULL DEFAULT 'website',\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"label\\\\\\\" TEXT,\\\\n \\\\\\\"sort_order\\\\\\\" INTEGER NOT NULL DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"platform\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"website\\\"},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"label\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"sort_order\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_links_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_links_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_links_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"847fd648\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileMetadataCollection\\\":{\\\"name\\\":\\\"profilemetadatacollection\\\",\\\"className\\\":\\\"ProfileMetadataCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileMetadataCollection\\\",\\\"collection\\\":\\\"profilemetadatas\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileMetadataCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getByProfile\\\":{\\\"name\\\":\\\"getByProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileMetadata[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadataObject\\\":{\\\"name\\\":\\\"getMetadataObject\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Record<string, string>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findProfilesByMetadata\\\":{\\\"name\\\":\\\"findProfilesByMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<string[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileMetadata\\\",\\\"exportName\\\":\\\"ProfileMetadataCollection\\\",\\\"collectionExportName\\\":\\\"ProfileMetadataCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_metadata\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_metadata\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"metafield_id\\\\\\\" UUID,\\\\n \\\\\\\"value\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"metafield_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_metafields\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"value\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_metadata_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_metadata_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_metadata_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_metadata_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"profile_metadata_metafield_id_idx\\\",\\\"columns\\\":[\\\"metafield_id\\\"]}],\\\"version\\\":\\\"d3ab1b70\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileMetafieldCollection\\\":{\\\"name\\\":\\\"profilemetafieldcollection\\\",\\\"className\\\":\\\"ProfileMetafieldCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileMetafieldCollection\\\",\\\"collection\\\":\\\"profilemetafields\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileMetafieldCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileMetafield | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOrCreateBySlug\\\":{\\\"name\\\":\\\"getOrCreateBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"defaults\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"ValidationSchema\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileMetafield>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileMetafield\\\",\\\"exportName\\\":\\\"ProfileMetafieldCollection\\\",\\\"collectionExportName\\\":\\\"ProfileMetafieldCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_metafields\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_metafields\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"validation\\\\\\\" JSON\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"validation\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_metafields_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_metafields_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_metafields_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"afe420df\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationshipCollection\\\":{\\\"name\\\":\\\"profilerelationshipcollection\\\",\\\"className\\\":\\\"ProfileRelationshipCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationshipCollection\\\",\\\"collection\\\":\\\"profilerelationships\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileRelationshipCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getFromProfile\\\":{\\\"name\\\":\\\"getFromProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"fromProfileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"typeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getToProfile\\\":{\\\"name\\\":\\\"getToProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"typeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getForProfile\\\":{\\\"name\\\":\\\"getForProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"typeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"exists\\\":{\\\"name\\\":\\\"exists\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"fromProfileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"toProfileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"typeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileRelationship\\\",\\\"exportName\\\":\\\"ProfileRelationshipCollection\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationships\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationships\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"from_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"to_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"context_profile_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"from_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"to_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_relationship_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"context_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationships_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_relationships_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationships_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_relationships_from_profile_id_idx\\\",\\\"columns\\\":[\\\"from_profile_id\\\"]},{\\\"name\\\":\\\"profile_relationships_to_profile_id_idx\\\",\\\"columns\\\":[\\\"to_profile_id\\\"]},{\\\"name\\\":\\\"profile_relationships_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]},{\\\"name\\\":\\\"profile_relationships_context_profile_id_idx\\\",\\\"columns\\\":[\\\"context_profile_id\\\"]}],\\\"version\\\":\\\"48878dba\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationshipTermCollection\\\":{\\\"name\\\":\\\"profilerelationshiptermcollection\\\",\\\"className\\\":\\\"ProfileRelationshipTermCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationshipTermCollection\\\",\\\"collection\\\":\\\"profilerelationshipterms\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileRelationshipTermCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getByRelationship\\\":{\\\"name\\\":\\\"getByRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipTerm[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveTerm\\\":{\\\"name\\\":\\\"getActiveTerm\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipTerm | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getHistoricalTerms\\\":{\\\"name\\\":\\\"getHistoricalTerms\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipTerm[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileRelationshipTerm\\\",\\\"exportName\\\":\\\"ProfileRelationshipTermCollection\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipTermCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationship_terms\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationship_terms\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"relationship_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"relationship_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_relationships\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationship_terms_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_relationship_terms_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationship_terms_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_relationship_terms_relationship_id_idx\\\",\\\"columns\\\":[\\\"relationship_id\\\"]}],\\\"version\\\":\\\"ef299102\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationshipTypeCollection\\\":{\\\"name\\\":\\\"profilerelationshiptypecollection\\\",\\\"className\\\":\\\"ProfileRelationshipTypeCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationshipTypeCollection\\\",\\\"collection\\\":\\\"profilerelationshiptypes\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileRelationshipTypeCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipType | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOrCreateBySlug\\\":{\\\"name\\\":\\\"getOrCreateBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"defaults\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"boolean\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipType>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getReciprocal\\\":{\\\"name\\\":\\\"getReciprocal\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileRelationshipType[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getDirectional\\\":{\\\"name\\\":\\\"getDirectional\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileRelationshipType[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileRelationshipType\\\",\\\"exportName\\\":\\\"ProfileRelationshipTypeCollection\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipTypeCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationship_types\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationship_types\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"reciprocal\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"reciprocal\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationship_types_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_relationship_types_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationship_types_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"719fe0d9\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileTypeCollection\\\":{\\\"name\\\":\\\"profiletypecollection\\\",\\\"className\\\":\\\"ProfileTypeCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileTypeCollection\\\",\\\"collection\\\":\\\"profiletypes\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/collections/ProfileTypeCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileType | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOrCreateBySlug\\\":{\\\"name\\\":\\\"getOrCreateBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"defaults\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileType>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOrCreateGlobalBySlug\\\":{\\\"name\\\":\\\"getOrCreateGlobalBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"defaults\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileType>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"ProfileType\\\",\\\"exportName\\\":\\\"ProfileTypeCollection\\\",\\\"collectionExportName\\\":\\\"ProfileTypeCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"profile_types\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_types\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_types_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_types_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_types_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"0fb37aeb\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ApiKey\\\":{\\\"name\\\":\\\"apikey\\\",\\\"className\\\":\\\"ApiKey\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ApiKey\\\",\\\"collection\\\":\\\"apikeys\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ApiKey.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"keyHash\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"keyPrefix\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"scopes\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"default\\\":[]},\\\"lastUsedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"expiresAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"revokedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"getProfile\\\":{\\\"name\\\":\\\"getProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isValid\\\":{\\\"name\\\":\\\"isValid\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hasScope\\\":{\\\"name\\\":\\\"hasScope\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"scope\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"revoke\\\":{\\\"name\\\":\\\"revoke\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordUsage\\\":{\\\"name\\\":\\\"recordUsage\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"hashKey\\\":{\\\"name\\\":\\\"hashKey\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"generate\\\":{\\\"name\\\":\\\"generate\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"verify\\\":{\\\"name\\\":\\\"verify\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<ApiKey | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"api_keys\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"revoke\\\"],\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ApiKey\\\",\\\"collectionExportName\\\":\\\"ApiKeyCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"api_keys\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"api_keys\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"key_hash\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"key_prefix\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"scopes\\\\\\\" JSON DEFAULT '[]',\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"expires_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"revoked_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"key_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"key_prefix\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"scopes\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":[]},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"expires_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"revoked_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"api_keys_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"api_keys_key_hash_idx\\\",\\\"columns\\\":[\\\"key_hash\\\"]},{\\\"name\\\":\\\"api_keys_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"api_keys_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"9b0d49e8\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:AuditLog\\\":{\\\"name\\\":\\\"auditlog\\\",\\\"className\\\":\\\"AuditLog\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:AuditLog\\\",\\\"collection\\\":\\\"auditlogs\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/AuditLog.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":true}}},\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"action\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"reason\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"changes\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"default\\\":{}},\\\"resourceType\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"resourceId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"occurredAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"default\\\":\\\"current_timestamp\\\",\\\"_meta\\\":{\\\"indexed\\\":true,\\\"default\\\":\\\"current_timestamp\\\"}},\\\"source\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"web\\\"},\\\"metadata\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"default\\\":{}},\\\"onBehalfOfId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"getProfile\\\":{\\\"name\\\":\\\"getProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOnBehalfOf\\\":{\\\"name\\\":\\\"getOnBehalfOf\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getEffectiveActor\\\":{\\\"name\\\":\\\"getEffectiveActor\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"record\\\":{\\\"name\\\":\\\"record\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"audit_logs\\\",\\\"sensitive\\\":true,\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\",\\\"allowSuperAdminBypass\\\":true},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"AuditLog\\\",\\\"collectionExportName\\\":\\\"AuditLogCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"audit_logs\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"audit_logs\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"action\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"reason\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"changes\\\\\\\" JSON DEFAULT '{}',\\\\n \\\\\\\"resource_type\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"resource_id\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"occurred_at\\\\\\\" TIMESTAMP DEFAULT current_timestamp,\\\\n \\\\\\\"source\\\\\\\" TEXT DEFAULT 'web',\\\\n \\\\\\\"metadata\\\\\\\" JSON DEFAULT '{}',\\\\n \\\\\\\"on_behalf_of_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"action\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"reason\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"changes\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":{}},\\\"resource_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"resource_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"occurred_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"current_timestamp\\\"},\\\"source\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"web\\\"},\\\"metadata\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":{}},\\\"on_behalf_of_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}}},\\\"indexes\\\":[{\\\"name\\\":\\\"audit_logs_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"audit_logs_resource_type_idx\\\",\\\"columns\\\":[\\\"resource_type\\\"]},{\\\"name\\\":\\\"audit_logs_resource_id_idx\\\",\\\"columns\\\":[\\\"resource_id\\\"]},{\\\"name\\\":\\\"audit_logs_occurred_at_idx\\\",\\\"columns\\\":[\\\"occurred_at\\\"]},{\\\"name\\\":\\\"audit_logs_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"audit_logs_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"audit_logs_on_behalf_of_id_idx\\\",\\\"columns\\\":[\\\"on_behalf_of_id\\\"]}],\\\"version\\\":\\\"769bd855\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:MagicLinkToken\\\":{\\\"name\\\":\\\"magiclinktoken\\\",\\\"className\\\":\\\"MagicLinkToken\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:MagicLinkToken\\\",\\\"collection\\\":\\\"magiclinktokens\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/MagicLinkToken.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"nostrIdentityId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"NostrIdentity\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"tokenHash\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"expiresAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"usedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"requestedFromIp\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"createdAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"hashToken\\\":{\\\"name\\\":\\\"hashToken\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"token\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"generate\\\":{\\\"name\\\":\\\"generate\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrIdentity\\\",\\\"type\\\":\\\"NostrIdentity\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"number\\\",\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateTokenResult>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"verify\\\":{\\\"name\\\":\\\"verify\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"token\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<MagicLinkToken | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"isValid\\\":{\\\"name\\\":\\\"isValid\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isExpired\\\":{\\\"name\\\":\\\"isExpired\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isUsed\\\":{\\\"name\\\":\\\"isUsed\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"markUsed\\\":{\\\"name\\\":\\\"markUsed\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNostrIdentity\\\":{\\\"name\\\":\\\"getNostrIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTimeRemainingSeconds\\\":{\\\"name\\\":\\\"getTimeRemainingSeconds\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"magic_link_tokens\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"exclude\\\":[\\\"*\\\"]},\\\"mcp\\\":{\\\"exclude\\\":[\\\"*\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\"]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"MagicLinkToken\\\",\\\"collectionExportName\\\":\\\"MagicLinkTokenCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"nostrIdentityId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"magic_link_tokens\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"magic_link_tokens\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"nostr_identity_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"token_hash\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"email\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"expires_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"requested_from_ip\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"nostr_identity_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"nostr_identities\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"token_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"expires_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"requested_from_ip\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"magic_link_tokens_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"magic_link_tokens_token_hash_idx\\\",\\\"columns\\\":[\\\"token_hash\\\"]},{\\\"name\\\":\\\"magic_link_tokens_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"magic_link_tokens_nostr_identity_id_idx\\\",\\\"columns\\\":[\\\"nostr_identity_id\\\"]}],\\\"version\\\":\\\"d60748fe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:NostrIdentity\\\":{\\\"name\\\":\\\"nostridentity\\\",\\\"className\\\":\\\"NostrIdentity\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:NostrIdentity\\\",\\\"collection\\\":\\\"nostridentities\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/NostrIdentity.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"pubkey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"encryptedPrivkey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryptionIv\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryptionTag\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"nip05Username\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"\\\"},\\\"lastUsedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"verifiedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"getProfile\\\":{\\\"name\\\":\\\"getProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByPubkey\\\":{\\\"name\\\":\\\"findByPubkey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByEmail\\\":{\\\"name\\\":\\\"findByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByNip05\\\":{\\\"name\\\":\\\"findByNip05\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"username\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<NostrIdentity | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"decryptPrivkey\\\":{\\\"name\\\":\\\"decryptPrivkey\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"masterSecret\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getKeypair\\\":{\\\"name\\\":\\\"getKeypair\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"masterSecret\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"object\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordUsage\\\":{\\\"name\\\":\\\"recordUsage\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"markVerified\\\":{\\\"name\\\":\\\"markVerified\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"isVerified\\\":{\\\"name\\\":\\\"isVerified\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNip05Identifier\\\":{\\\"name\\\":\\\"getNip05Identifier\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"domain\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"nostr_identities\\\",\\\"sensitive\\\":true,\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"NostrIdentity\\\",\\\"collectionExportName\\\":\\\"NostrIdentityCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"nostr_identities\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"nostr_identities\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"pubkey\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encrypted_privkey\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encryption_iv\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"encryption_tag\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"email\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"nip05_username\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"verified_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"pubkey\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encrypted_privkey\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryption_iv\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"encryption_tag\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"nip05_username\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"verified_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"nostr_identities_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"nostr_identities_pubkey_idx\\\",\\\"columns\\\":[\\\"pubkey\\\"]},{\\\"name\\\":\\\"nostr_identities_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"nostr_identities_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"92eda375\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:OidcIdentity\\\":{\\\"name\\\":\\\"oidcidentity\\\",\\\"className\\\":\\\"OidcIdentity\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:OidcIdentity\\\",\\\"collection\\\":\\\"oidcidentities\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/OidcIdentity.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"provider\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"issuer\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"subject\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"indexed\\\":true}},\\\"identityKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"unique\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"lastUsedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"getProfile\\\":{\\\"name\\\":\\\"getProfile\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findBySubject\\\":{\\\"name\\\":\\\"findBySubject\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"issuer\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"subject\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<OidcIdentity | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"buildIdentityKey\\\":{\\\"name\\\":\\\"buildIdentityKey\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"issuer\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"subject\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"string\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findOrCreate\\\":{\\\"name\\\":\\\"findOrCreate\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"profile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"SmrtObjectOptions\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"recordUsage\\\":{\\\"name\\\":\\\"recordUsage\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"oidc_identities\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"OidcIdentity\\\",\\\"collectionExportName\\\":\\\"OidcIdentityCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"oidc_identities\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"oidc_identities\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"provider\\\\\\\" TEXT,\\\\n \\\\\\\"issuer\\\\\\\" TEXT,\\\\n \\\\\\\"subject\\\\\\\" TEXT,\\\\n \\\\\\\"identity_key\\\\\\\" TEXT UNIQUE,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"last_used_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"provider\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"issuer\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"subject\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"identity_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":true},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"last_used_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"oidc_identities_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"oidc_identities_issuer_idx\\\",\\\"columns\\\":[\\\"issuer\\\"]},{\\\"name\\\":\\\"oidc_identities_subject_idx\\\",\\\"columns\\\":[\\\"subject\\\"]},{\\\"name\\\":\\\"oidc_identities_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"oidc_identities_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"925387ea\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:OidcProfileEmailReservation\\\":{\\\"name\\\":\\\"oidcprofileemailreservation\\\",\\\"className\\\":\\\"OidcProfileEmailReservation\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:OidcProfileEmailReservation\\\",\\\"collection\\\":\\\"oidcprofileemailreservations\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/OidcProfileEmailReservation.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true,\\\"unique\\\":true}},\\\"emailKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true,\\\"unique\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"oidc_profile_email_reservations\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"OidcProfileEmailReservation\\\",\\\"collectionExportName\\\":\\\"OidcProfileEmailReservationCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"emailKey\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"oidc_profile_email_reservations\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"oidc_profile_email_reservations\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL UNIQUE,\\\\n \\\\\\\"email_key\\\\\\\" TEXT NOT NULL UNIQUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":true,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"oidc_profile_email_reservations_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"oidc_profile_email_reservations_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"01586e67\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:Profile\\\":{\\\"name\\\":\\\"profile\\\",\\\"className\\\":\\\"Profile\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:Profile\\\",\\\"collection\\\":\\\"profiles\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/Profile.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"typeId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileType\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"emailKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"indexed\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"isPublic\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":false,\\\"_meta\\\":{\\\"default\\\":false}},\\\"metadata\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileMetadata\\\"},\\\"relationshipsFrom\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"fromProfileId\\\"}},\\\"relationshipsTo\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"toProfileId\\\"}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTypeSlug\\\":{\\\"name\\\":\\\"getTypeSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTypeBySlug\\\":{\\\"name\\\":\\\"setTypeBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addMetadata\\\":{\\\"name\\\":\\\"addMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Record<string, string>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"updateMetadata\\\":{\\\"name\\\":\\\"updateMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metadata\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeMetadata\\\":{\\\"name\\\":\\\"removeMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getLinks\\\":{\\\"name\\\":\\\"getLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setLinks\\\":{\\\"name\\\":\\\"setLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"links\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addRelationship\\\":{\\\"name\\\":\\\"addRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"contextProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelationships\\\":{\\\"name\\\":\\\"getRelationships\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'from' | 'to' | 'all'\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelatedProfiles\\\":{\\\"name\\\":\\\"getRelatedProfiles\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeRelationship\\\":{\\\"name\\\":\\\"removeRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateBio\\\":{\\\"name\\\":\\\"generateBio\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matches\\\":{\\\"name\\\":\\\"matches\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"criteria\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByMetadata\\\":{\\\"name\\\":\\\"findByMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_typeSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findRelated\\\":{\\\"name\\\":\\\"findRelated\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"searchByEmail\\\":{\\\"name\\\":\\\"searchByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getApiKeys\\\":{\\\"name\\\":\\\"getApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveApiKeys\\\":{\\\"name\\\":\\\"getActiveApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateApiKey\\\":{\\\"name\\\":\\\"generateApiKey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOidcIdentities\\\":{\\\"name\\\":\\\"getOidcIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkOidcIdentity\\\":{\\\"name\\\":\\\"linkOidcIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNostrIdentities\\\":{\\\"name\\\":\\\"getNostrIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<NostrIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkNostrIdentity\\\":{\\\"name\\\":\\\"linkNostrIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAuditLogs\\\":{\\\"name\\\":\\\"getAuditLogs\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordAction\\\":{\\\"name\\\":\\\"recordAction\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'web' | 'cli' | 'ci' | 'webhook' | 'mcp'\\\",\\\"Record<string, unknown>\\\",\\\"Profile | null\\\"]}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"Profile\\\",\\\"collectionExportName\\\":\\\"ProfileCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"typeId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profiles\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profiles\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"email_key\\\\\\\" TEXT,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"is_public\\\\\\\" BOOLEAN DEFAULT FALSE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"is_public\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profiles_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profiles_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profiles_email_key_idx\\\",\\\"columns\\\":[\\\"email_key\\\"]},{\\\"name\\\":\\\"profiles_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profiles_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]}],\\\"version\\\":\\\"f4a7b632\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileAsset\\\":{\\\"name\\\":\\\"profileasset\\\",\\\"className\\\":\\\"ProfileAsset\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileAsset\\\",\\\"collection\\\":\\\"profileassets\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileAsset.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true,\\\"onDelete\\\":\\\"CASCADE\\\"}},\\\"assetId\\\":{\\\"type\\\":\\\"crossPackageRef\\\",\\\"required\\\":true,\\\"related\\\":\\\"@happyvertical/smrt-assets:Asset\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"CASCADE\\\"}},\\\"relationship\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"sortOrder\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"profile_assets\\\",\\\"conflictColumns\\\":[\\\"profile_id\\\",\\\"asset_id\\\",\\\"relationship\\\"],\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileAsset\\\",\\\"collectionExportName\\\":\\\"ProfileAssetCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"assetId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"crossPackageRef\\\"},{\\\"field\\\":\\\"relationship\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"sortOrder\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_assets\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_assets\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"asset_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"relationship\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"sort_order\\\\\\\" INTEGER NOT NULL DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"asset_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"crossPackageRef\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"relationship\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"sort_order\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_assets_profile_id_asset_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\",\\\"asset_id\\\",\\\"relationship\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_assets_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"profile_assets_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_assets_asset_id_idx\\\",\\\"columns\\\":[\\\"asset_id\\\"]}],\\\"version\\\":\\\"d0d7c2a2\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileLink\\\":{\\\"name\\\":\\\"profilelink\\\",\\\"className\\\":\\\"ProfileLink\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileLink\\\",\\\"collection\\\":\\\"profilelinks\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileLink.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true,\\\"onDelete\\\":\\\"CASCADE\\\"}},\\\"platform\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"website\\\",\\\"maxLength\\\":32,\\\"_meta\\\":{\\\"required\\\":true,\\\"maxLength\\\":32}},\\\"url\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"maxLength\\\":2048,\\\"_meta\\\":{\\\"required\\\":true,\\\"maxLength\\\":2048}},\\\"label\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"maxLength\\\":200,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"maxLength\\\":200}},\\\"sortOrder\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":true,\\\"default\\\":0}},\\\"methods\\\":{\\\"getSlug\\\":{\\\"name\\\":\\\"getSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string | null | undefined>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"...args\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"profile_links\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileLink\\\",\\\"collectionExportName\\\":\\\"ProfileLinkCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"platform\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"platform\\\",\\\"rule\\\":\\\"maxLength\\\",\\\"value\\\":32,\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"url\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"url\\\",\\\"rule\\\":\\\"maxLength\\\",\\\"value\\\":2048,\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"label\\\",\\\"rule\\\":\\\"maxLength\\\",\\\"value\\\":200,\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"sortOrder\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"integer\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_links\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_links\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"platform\\\\\\\" TEXT NOT NULL DEFAULT 'website',\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"label\\\\\\\" TEXT,\\\\n \\\\\\\"sort_order\\\\\\\" INTEGER NOT NULL DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"CASCADE\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"platform\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"website\\\"},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"label\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"sort_order\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_links_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_links_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_links_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]}],\\\"version\\\":\\\"847fd648\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileMetadata\\\":{\\\"name\\\":\\\"profilemetadata\\\",\\\"className\\\":\\\"ProfileMetadata\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileMetadata\\\",\\\"collection\\\":\\\"profilemetadatas\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileMetadata.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"profileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"metafieldId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileMetafield\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"value\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}}},\\\"methods\\\":{\\\"validate\\\":{\\\"name\\\":\\\"validate\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetafieldSlug\\\":{\\\"name\\\":\\\"getMetafieldSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileMetadata\\\",\\\"collectionExportName\\\":\\\"ProfileMetadataCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"profileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"metafieldId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"value\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_metadata\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_metadata\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"profile_id\\\\\\\" UUID,\\\\n \\\\\\\"metafield_id\\\\\\\" UUID,\\\\n \\\\\\\"value\\\\\\\" TEXT DEFAULT ''\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"metafield_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_metafields\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"value\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_metadata_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_metadata_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_metadata_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_metadata_profile_id_idx\\\",\\\"columns\\\":[\\\"profile_id\\\"]},{\\\"name\\\":\\\"profile_metadata_metafield_id_idx\\\",\\\"columns\\\":[\\\"metafield_id\\\"]}],\\\"version\\\":\\\"d3ab1b70\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileMetafield\\\":{\\\"name\\\":\\\"profilemetafield\\\",\\\"className\\\":\\\"ProfileMetafield\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileMetafield\\\",\\\"collection\\\":\\\"profilemetafields\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileMetafield.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"validation\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileMetafield | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"registerValidator\\\":{\\\"name\\\":\\\"registerValidator\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"validator\\\",\\\"type\\\":\\\"ValidatorFunction\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getValidator\\\":{\\\"name\\\":\\\"getValidator\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"ValidatorFunction | undefined\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"validateValue\\\":{\\\"name\\\":\\\"validateValue\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileMetafield\\\",\\\"collectionExportName\\\":\\\"ProfileMetafieldCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_metafields\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_metafields\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"validation\\\\\\\" JSON\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"validation\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_metafields_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_metafields_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_metafields_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"afe420df\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationship\\\":{\\\"name\\\":\\\"profilerelationship\\\",\\\"className\\\":\\\"ProfileRelationship\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationship\\\",\\\"collection\\\":\\\"profilerelationships\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileRelationship.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"fromProfileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"toProfileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"Profile\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"typeId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileRelationshipType\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"contextProfileId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"Profile\\\"},\\\"terms\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationshipTerm\\\"}},\\\"methods\\\":{\\\"getTypeSlug\\\":{\\\"name\\\":\\\"getTypeSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addTerm\\\":{\\\"name\\\":\\\"addTerm\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"startedAt\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"endedAt\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"endCurrentTerm\\\":{\\\"name\\\":\\\"endCurrentTerm\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"endedAt\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTerms\\\":{\\\"name\\\":\\\"getTerms\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileRelationshipTerm[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveTerm\\\":{\\\"name\\\":\\\"getActiveTerm\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileRelationshipTerm | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"delete\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileRelationship\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"fromProfileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"toProfileId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"typeId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationships\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationships\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"from_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"to_profile_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"context_profile_id\\\\\\\" UUID\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"from_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"to_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_relationship_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"context_profile_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profiles\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationships_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_relationships_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationships_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_relationships_from_profile_id_idx\\\",\\\"columns\\\":[\\\"from_profile_id\\\"]},{\\\"name\\\":\\\"profile_relationships_to_profile_id_idx\\\",\\\"columns\\\":[\\\"to_profile_id\\\"]},{\\\"name\\\":\\\"profile_relationships_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]},{\\\"name\\\":\\\"profile_relationships_context_profile_id_idx\\\",\\\"columns\\\":[\\\"context_profile_id\\\"]}],\\\"version\\\":\\\"48878dba\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationshipTerm\\\":{\\\"name\\\":\\\"profilerelationshipterm\\\",\\\"className\\\":\\\"ProfileRelationshipTerm\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationshipTerm\\\",\\\"collection\\\":\\\"profilerelationshipterms\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileRelationshipTerm.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"relationshipId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"startedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"endedAt\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"isActive\\\":{\\\"name\\\":\\\"isActive\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"boolean\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"end\\\":{\\\"name\\\":\\\"end\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"endedAt\\\",\\\"type\\\":\\\"Date\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getDurationDays\\\":{\\\"name\\\":\\\"getDurationDays\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"number\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileRelationshipTerm\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipTermCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"relationshipId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"startedAt\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"datetime\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationship_terms\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationship_terms\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"relationship_id\\\\\\\" UUID,\\\\n \\\\\\\"started_at\\\\\\\" TIMESTAMP,\\\\n \\\\\\\"ended_at\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"relationship_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_relationships\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"started_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false},\\\"ended_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationship_terms_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_relationship_terms_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationship_terms_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]},{\\\"name\\\":\\\"profile_relationship_terms_relationship_id_idx\\\",\\\"columns\\\":[\\\"relationship_id\\\"]}],\\\"version\\\":\\\"ef299102\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileRelationshipType\\\":{\\\"name\\\":\\\"profilerelationshiptype\\\",\\\"className\\\":\\\"ProfileRelationshipType\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileRelationshipType\\\",\\\"collection\\\":\\\"profilerelationshiptypes\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileRelationshipType.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"reciprocal\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":true}},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileRelationshipType | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"registerReciprocalHandler\\\":{\\\"name\\\":\\\"registerReciprocalHandler\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"handler\\\",\\\"type\\\":\\\"ReciprocalHandler\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getReciprocalHandler\\\":{\\\"name\\\":\\\"getReciprocalHandler\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"ReciprocalHandler | undefined\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"isReciprocal\\\":{\\\"name\\\":\\\"isReciprocal\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileRelationshipType\\\",\\\"collectionExportName\\\":\\\"ProfileRelationshipTypeCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_relationship_types\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_relationship_types\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"reciprocal\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"reciprocal\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_relationship_types_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"profile_relationship_types_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_relationship_types_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"719fe0d9\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:ProfileType\\\":{\\\"name\\\":\\\"profiletype\\\",\\\"className\\\":\\\"ProfileType\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:ProfileType\\\",\\\"collection\\\":\\\"profiletypes\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileType.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true,\\\"mode\\\":\\\"optional\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false}},\\\"methods\\\":{\\\"getBySlug\\\":{\\\"name\\\":\\\"getBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<ProfileType | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\"]},\\\"mcp\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\"]},\\\"cli\\\":{\\\"skipApiCheck\\\":true},\\\"tenantScoped\\\":{\\\"mode\\\":\\\"optional\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"ProfileType\\\",\\\"collectionExportName\\\":\\\"ProfileTypeCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profile_types\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profile_types\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profile_types_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profile_types_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profile_types_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"0fb37aeb\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:Person\\\":{\\\"name\\\":\\\"person\\\",\\\"className\\\":\\\"Person\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:Person\\\",\\\"collection\\\":\\\"profiles\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileTypes.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true}}},\\\"typeId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileType\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"emailKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"indexed\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"isPublic\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":false,\\\"_meta\\\":{\\\"default\\\":false}},\\\"metadata\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileMetadata\\\"},\\\"relationshipsFrom\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"fromProfileId\\\"}},\\\"relationshipsTo\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"toProfileId\\\"}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTypeSlug\\\":{\\\"name\\\":\\\"getTypeSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTypeBySlug\\\":{\\\"name\\\":\\\"setTypeBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addMetadata\\\":{\\\"name\\\":\\\"addMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Record<string, string>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"updateMetadata\\\":{\\\"name\\\":\\\"updateMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metadata\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeMetadata\\\":{\\\"name\\\":\\\"removeMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getLinks\\\":{\\\"name\\\":\\\"getLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setLinks\\\":{\\\"name\\\":\\\"setLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"links\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addRelationship\\\":{\\\"name\\\":\\\"addRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"contextProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelationships\\\":{\\\"name\\\":\\\"getRelationships\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'from' | 'to' | 'all'\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelatedProfiles\\\":{\\\"name\\\":\\\"getRelatedProfiles\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeRelationship\\\":{\\\"name\\\":\\\"removeRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateBio\\\":{\\\"name\\\":\\\"generateBio\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matches\\\":{\\\"name\\\":\\\"matches\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"criteria\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByMetadata\\\":{\\\"name\\\":\\\"findByMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_typeSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findRelated\\\":{\\\"name\\\":\\\"findRelated\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"searchByEmail\\\":{\\\"name\\\":\\\"searchByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getApiKeys\\\":{\\\"name\\\":\\\"getApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveApiKeys\\\":{\\\"name\\\":\\\"getActiveApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateApiKey\\\":{\\\"name\\\":\\\"generateApiKey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOidcIdentities\\\":{\\\"name\\\":\\\"getOidcIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkOidcIdentity\\\":{\\\"name\\\":\\\"linkOidcIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNostrIdentities\\\":{\\\"name\\\":\\\"getNostrIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<NostrIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkNostrIdentity\\\":{\\\"name\\\":\\\"linkNostrIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAuditLogs\\\":{\\\"name\\\":\\\"getAuditLogs\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordAction\\\":{\\\"name\\\":\\\"recordAction\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'web' | 'cli' | 'ci' | 'webhook' | 'mcp'\\\",\\\"Record<string, unknown>\\\",\\\"Profile | null\\\"]}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"tableName\\\":\\\"profiles\\\"},\\\"extends\\\":\\\"Profile\\\",\\\"exportName\\\":\\\"Person\\\",\\\"collectionExportName\\\":\\\"PersonCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"typeId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profiles\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profiles\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"email_key\\\\\\\" TEXT,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"is_public\\\\\\\" BOOLEAN DEFAULT FALSE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"is_public\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profiles_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profiles_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profiles_email_key_idx\\\",\\\"columns\\\":[\\\"email_key\\\"]},{\\\"name\\\":\\\"profiles_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profiles_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]}],\\\"version\\\":\\\"2043b736\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:Organization\\\":{\\\"name\\\":\\\"organization\\\",\\\"className\\\":\\\"Organization\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:Organization\\\",\\\"collection\\\":\\\"profiles\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileTypes.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true}}},\\\"typeId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileType\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"emailKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"indexed\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"isPublic\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":false,\\\"_meta\\\":{\\\"default\\\":false}},\\\"metadata\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileMetadata\\\"},\\\"relationshipsFrom\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"fromProfileId\\\"}},\\\"relationshipsTo\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"toProfileId\\\"}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTypeSlug\\\":{\\\"name\\\":\\\"getTypeSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTypeBySlug\\\":{\\\"name\\\":\\\"setTypeBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addMetadata\\\":{\\\"name\\\":\\\"addMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Record<string, string>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"updateMetadata\\\":{\\\"name\\\":\\\"updateMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metadata\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeMetadata\\\":{\\\"name\\\":\\\"removeMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getLinks\\\":{\\\"name\\\":\\\"getLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setLinks\\\":{\\\"name\\\":\\\"setLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"links\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addRelationship\\\":{\\\"name\\\":\\\"addRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"contextProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelationships\\\":{\\\"name\\\":\\\"getRelationships\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'from' | 'to' | 'all'\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelatedProfiles\\\":{\\\"name\\\":\\\"getRelatedProfiles\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeRelationship\\\":{\\\"name\\\":\\\"removeRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateBio\\\":{\\\"name\\\":\\\"generateBio\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matches\\\":{\\\"name\\\":\\\"matches\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"criteria\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByMetadata\\\":{\\\"name\\\":\\\"findByMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_typeSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findRelated\\\":{\\\"name\\\":\\\"findRelated\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"searchByEmail\\\":{\\\"name\\\":\\\"searchByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getApiKeys\\\":{\\\"name\\\":\\\"getApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveApiKeys\\\":{\\\"name\\\":\\\"getActiveApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateApiKey\\\":{\\\"name\\\":\\\"generateApiKey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOidcIdentities\\\":{\\\"name\\\":\\\"getOidcIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkOidcIdentity\\\":{\\\"name\\\":\\\"linkOidcIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNostrIdentities\\\":{\\\"name\\\":\\\"getNostrIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<NostrIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkNostrIdentity\\\":{\\\"name\\\":\\\"linkNostrIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAuditLogs\\\":{\\\"name\\\":\\\"getAuditLogs\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordAction\\\":{\\\"name\\\":\\\"recordAction\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'web' | 'cli' | 'ci' | 'webhook' | 'mcp'\\\",\\\"Record<string, unknown>\\\",\\\"Profile | null\\\"]}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"tableName\\\":\\\"profiles\\\"},\\\"extends\\\":\\\"Profile\\\",\\\"exportName\\\":\\\"Organization\\\",\\\"collectionExportName\\\":\\\"OrganizationCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"typeId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profiles\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profiles\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"email_key\\\\\\\" TEXT,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"is_public\\\\\\\" BOOLEAN DEFAULT FALSE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"is_public\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profiles_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profiles_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profiles_email_key_idx\\\",\\\"columns\\\":[\\\"email_key\\\"]},{\\\"name\\\":\\\"profiles_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profiles_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]}],\\\"version\\\":\\\"573ebccc\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"},\\\"@happyvertical/smrt-profiles:Bot\\\":{\\\"name\\\":\\\"bot\\\",\\\"className\\\":\\\"Bot\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-profiles:Bot\\\",\\\"collection\\\":\\\"profiles\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/profiles/src/models/ProfileTypes.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-profiles\\\",\\\"fields\\\":{\\\"created_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"updated_at\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true,\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":false,\\\"autoPopulate\\\":true,\\\"nullable\\\":true}}},\\\"typeId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":true,\\\"related\\\":\\\"ProfileType\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"email\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"emailKey\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"indexed\\\":true,\\\"readonly\\\":true},\\\"readonly\\\":true},\\\"name\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"description\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false},\\\"isPublic\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":false,\\\"_meta\\\":{\\\"default\\\":false}},\\\"metadata\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileMetadata\\\"},\\\"relationshipsFrom\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"fromProfileId\\\"}},\\\"relationshipsTo\\\":{\\\"type\\\":\\\"oneToMany\\\",\\\"required\\\":false,\\\"related\\\":\\\"ProfileRelationship\\\",\\\"_meta\\\":{\\\"foreignKey\\\":\\\"toProfileId\\\"}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTypeSlug\\\":{\\\"name\\\":\\\"getTypeSlug\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTypeBySlug\\\":{\\\"name\\\":\\\"setTypeBySlug\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"slug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addMetadata\\\":{\\\"name\\\":\\\"addMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getMetadata\\\":{\\\"name\\\":\\\"getMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<Record<string, string>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"updateMetadata\\\":{\\\"name\\\":\\\"updateMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metadata\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeMetadata\\\":{\\\"name\\\":\\\"removeMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getLinks\\\":{\\\"name\\\":\\\"getLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setLinks\\\":{\\\"name\\\":\\\"setLinks\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"links\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true}],\\\"returnType\\\":\\\"Promise<ProfileLink[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAssets\\\":{\\\"name\\\":\\\"getAssets\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Asset[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addAsset\\\":{\\\"name\\\":\\\"addAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"asset\\\",\\\"type\\\":\\\"Asset\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true,\\\"default\\\":\\\"attachment\\\"},{\\\"name\\\":\\\"sortOrder\\\",\\\"type\\\":\\\"any\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeAsset\\\":{\\\"name\\\":\\\"removeAsset\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"assetId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationship\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"addRelationship\\\":{\\\"name\\\":\\\"addRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"contextProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelationships\\\":{\\\"name\\\":\\\"getRelationships\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'from' | 'to' | 'all'\\\"]}],\\\"returnType\\\":\\\"Promise<ProfileRelationship[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getRelatedProfiles\\\":{\\\"name\\\":\\\"getRelatedProfiles\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeRelationship\\\":{\\\"name\\\":\\\"removeRelationship\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"toProfile\\\",\\\"type\\\":\\\"Profile\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateBio\\\":{\\\"name\\\":\\\"generateBio\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<string>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"matches\\\":{\\\"name\\\":\\\"matches\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"criteria\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByMetadata\\\":{\\\"name\\\":\\\"findByMetadata\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_metafieldSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_value\\\",\\\"type\\\":\\\"unknown\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findByType\\\":{\\\"name\\\":\\\"findByType\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_typeSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"findRelated\\\":{\\\"name\\\":\\\"findRelated\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_profileId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"_relationshipSlug\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<Profile[]>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"searchByEmail\\\":{\\\"name\\\":\\\"searchByEmail\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"_email\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Profile | null>\\\",\\\"isStatic\\\":true,\\\"isPublic\\\":true},\\\"getApiKeys\\\":{\\\"name\\\":\\\"getApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getActiveApiKeys\\\":{\\\"name\\\":\\\"getActiveApiKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<ApiKey[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"generateApiKey\\\":{\\\"name\\\":\\\"generateApiKey\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\",\\\"string[]\\\",\\\"Date | null\\\"]}],\\\"returnType\\\":\\\"Promise<GenerateKeyResult>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOidcIdentities\\\":{\\\"name\\\":\\\"getOidcIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<OidcIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkOidcIdentity\\\":{\\\"name\\\":\\\"linkOidcIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"oidcData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<OidcIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getNostrIdentities\\\":{\\\"name\\\":\\\"getNostrIdentities\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<NostrIdentity[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"linkNostrIdentity\\\":{\\\"name\\\":\\\"linkNostrIdentity\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"nostrData\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<NostrIdentity>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getAuditLogs\\\":{\\\"name\\\":\\\"getAuditLogs\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"limit\\\",\\\"type\\\":\\\"number\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<AuditLog[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"recordAction\\\":{\\\"name\\\":\\\"recordAction\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":false,\\\"typeUnresolved\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"'web' | 'cli' | 'ci' | 'webhook' | 'mcp'\\\",\\\"Record<string, unknown>\\\",\\\"Profile | null\\\"]}],\\\"returnType\\\":\\\"Promise<AuditLog>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableStrategy\\\":\\\"sti\\\",\\\"tableName\\\":\\\"profiles\\\"},\\\"extends\\\":\\\"Profile\\\",\\\"exportName\\\":\\\"Bot\\\",\\\"collectionExportName\\\":\\\"BotCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"typeId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"foreignKey\\\"},{\\\"field\\\":\\\"name\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"profiles\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"profiles\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"_meta_type\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"_meta_data\\\\\\\" JSON,\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"type_id\\\\\\\" UUID,\\\\n \\\\\\\"email\\\\\\\" TEXT,\\\\n \\\\\\\"email_key\\\\\\\" TEXT,\\\\n \\\\\\\"name\\\\\\\" TEXT DEFAULT '',\\\\n \\\\\\\"description\\\\\\\" TEXT,\\\\n \\\\\\\"is_public\\\\\\\" BOOLEAN DEFAULT FALSE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"_meta_type\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"_meta_data\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":false},\\\"type_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"profile_types\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"NO ACTION\\\",\\\"onUpdate\\\":\\\"CASCADE\\\"}},\\\"email\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"email_key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"name\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"default\\\":\\\"\\\"},\\\"description\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false},\\\"is_public\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"default\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"profiles_slug_context_meta_type_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\",\\\"_meta_type\\\"],\\\"unique\\\":true,\\\"nullsNotDistinct\\\":true},{\\\"name\\\":\\\"profiles_meta_type_idx\\\",\\\"columns\\\":[\\\"_meta_type\\\"]},{\\\"name\\\":\\\"profiles_email_key_idx\\\",\\\"columns\\\":[\\\"email_key\\\"]},{\\\"name\\\":\\\"profiles_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"profiles_type_id_idx\\\",\\\"columns\\\":[\\\"type_id\\\"]}],\\\"version\\\":\\\"2a1c7716\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-profiles\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-assets\\\",\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-prompts\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"stampsConstructors\\\":true}\"));\n","/**\n * Agent (bot) profile resolution (#2995).\n *\n * An automated agent that participates in a conversation is still an author,\n * and every authoring seam in the framework — `ChatMessage.senderProfileId`,\n * `ChatParticipant.profileId`, `ChatReaction.profileId`, a persona's\n * `actsAsProfileId` — is a `crossPackageRef` to a {@link Profile} and therefore\n * a native uuid column on PostgreSQL/DuckDB. A slug-style agent identifier\n * (`anytown_site_assistant`) is not a representable author there: it fails the\n * uuid cast (22P02) at the boundary that owns it.\n *\n * `Profile` already models this: the `bot` profile type is \"automated agents,\n * bots, and AI entities\". This module is the owning-package API that turns a\n * stable agent identifier into that Profile's uuid, so consumers never have to\n * mint bot profiles themselves and never have to weaken a uuid column to text.\n *\n * Identity is keyed on `(tenantId, slug = agentId, context =\n * {@link AGENT_PROFILE_CONTEXT})`. The reserved slug context keeps an agent\n * profile from ever colliding with an unrelated human/organization profile that\n * happens to share the slug, and matches the model's\n * `(tenant_id, slug, context, _meta_type)` unique key.\n *\n * @module\n */\n\nimport type { ProfileCollection } from './collections/ProfileCollection';\nimport { ProfileTypeCollection } from './collections/ProfileTypeCollection';\nimport type { Profile } from './models/Profile';\n\n/**\n * Reserved slug context for agent-owned profiles.\n *\n * Agent identifiers come from application configuration, not from the profile\n * namespace, so they are scoped into their own slug context rather than\n * competing with person/organization slugs.\n */\nexport const AGENT_PROFILE_CONTEXT = 'smrt:agent';\n\n/** Slug of the {@link ProfileType} agent profiles are classified under. */\nexport const AGENT_PROFILE_TYPE_SLUG = 'bot';\n\n/** Inputs for {@link resolveAgentProfile}. */\nexport interface ResolveAgentProfileParams {\n /** Stable agent identifier (e.g. `anytown_site_assistant`). */\n agentId: string;\n /** Owning tenant, or `null` for an untenanted agent. */\n tenantId?: string | null;\n /** Display name for a newly created profile. Defaults to `agentId`. */\n name?: string;\n}\n\n/**\n * Resolve — creating on first use — the {@link Profile} an agent authors as.\n *\n * The lookup is tenant-bound: an agent identifier resolves to a distinct\n * profile per tenant, so one tenant's assistant can never author into another\n * tenant's conversation. Resolution is idempotent; repeated calls for the same\n * `(tenantId, agentId)` return the same profile.\n *\n * @param profiles - Profile collection bound to the caller's database options.\n * @param params - Agent identity to resolve.\n * @returns The agent's profile, whose `id` is a real uuid.\n * @throws Error when `agentId` is empty.\n */\nexport async function resolveAgentProfile(\n profiles: ProfileCollection,\n params: ResolveAgentProfileParams,\n): Promise<Profile> {\n const agentId = params.agentId?.trim();\n if (!agentId) {\n throw new Error('resolveAgentProfile requires a non-empty agentId');\n }\n const tenantId = params.tenantId ?? null;\n const key = { slug: agentId, context: AGENT_PROFILE_CONTEXT, tenantId };\n\n // First use races (two simultaneous first turns for one agent) are resolved by\n // converging on the natural key rather than by whoever's INSERT won: each\n // attempt re-reads before and after writing, so a racer whose own write lost\n // to a revision conflict or to the `(tenant_id, slug, context)` upsert still\n // returns the surviving row instead of a dangling id. Two attempts suffice —\n // the loser of the first is a plain read on the second.\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n const existing = await profiles.get(key);\n if (existing) return existing;\n\n try {\n const profileTypes = await ProfileTypeCollection.create(profiles.options);\n const agentType = await profileTypes.getOrCreateBySlug(\n AGENT_PROFILE_TYPE_SLUG,\n {\n name: 'Bot',\n description: 'Automated agents, bots, and AI entities',\n },\n );\n\n const profile = await profiles.create({\n ...key,\n typeId: agentType.id as string,\n name: params.name?.trim() || agentId,\n });\n await profile.save();\n } catch (error) {\n lastError = error;\n }\n\n const settled = await profiles.get(key);\n if (settled) return settled;\n }\n\n throw new Error(\n `Could not resolve an agent profile for '${agentId}'${\n lastError instanceof Error ? `: ${lastError.message}` : ''\n }`,\n );\n}\n\n/**\n * Resolve an agent profile and return its uuid.\n *\n * Convenience wrapper for the common case — an authoring seam that needs the\n * id, not the row.\n *\n * @param profiles - Profile collection bound to the caller's database options.\n * @param params - Agent identity to resolve.\n * @returns The agent profile's uuid.\n */\nexport async function resolveAgentProfileId(\n profiles: ProfileCollection,\n params: ResolveAgentProfileParams,\n): Promise<string> {\n const profile = await resolveAgentProfile(profiles, params);\n const id = profile.id;\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n `Agent profile for '${params.agentId}' was persisted without an id`,\n );\n }\n return id;\n}\n","import type { AuditEntry, AuditWriter } from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport type { AuditLogCollection } from './collections/AuditLogCollection.js';\nimport { AuditLog } from './models/AuditLog.js';\n\n/** Profiles owns audit persistence; core only owns the mutation contract. */\nexport function createAuditWriter(): AuditWriter {\n return async (entry: AuditEntry, db: DatabaseInterface) => {\n const log = new AuditLog({\n db,\n profileId: entry.actorId,\n onBehalfOfId: entry.onBehalfOfId,\n tenantId: entry.tenantId,\n action: entry.action,\n resourceType: entry.resourceType,\n resourceId: entry.resourceId,\n source: entry.source ?? 'web',\n reason: entry.reason ?? '',\n changes: entry.changes,\n });\n await log.initialize();\n await log.save();\n };\n}\n\nexport interface AuditFilter {\n profileId?: string;\n resourceType?: string;\n resourceId?: string;\n from?: Date;\n to?: Date;\n limit?: number;\n}\n\n/** Consumer checks both audit permission and access to the referenced resource. */\nexport type AuthorizeAuditRead = (\n entry: AuditLog,\n) => boolean | Promise<boolean>;\n\n/** No generated read routes: consumers expose this fail-closed permission seam. */\nexport async function readAuditTrail(\n logs: AuditLogCollection,\n authorize: AuthorizeAuditRead,\n filter: AuditFilter = {},\n): Promise<AuditLog[]> {\n if (typeof authorize !== 'function')\n throw new Error('Audit reads require consumer authorization');\n const limit = filter.limit ?? 100;\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1000) {\n throw new Error('Audit limit must be an integer from 1 to 1000');\n }\n for (const date of [filter.from, filter.to]) {\n if (\n date !== undefined &&\n (!(date instanceof Date) || !Number.isFinite(date.getTime()))\n ) {\n throw new Error('Audit date filters must be valid Dates');\n }\n }\n if (filter.from && filter.to && filter.from > filter.to)\n throw new Error('Audit date range is reversed');\n const where: Record<string, unknown> = {};\n for (const key of ['profileId', 'resourceType', 'resourceId'] as const) {\n if (filter[key] !== undefined) where[key] = filter[key];\n }\n if (filter.from) where['occurredAt >='] = filter.from;\n if (filter.to) where['occurredAt <='] = filter.to;\n const candidates = await logs.list({\n where,\n orderBy: 'occurredAt DESC',\n limit,\n });\n const visible: AuditLog[] = [];\n for (const entry of candidates) {\n // A broken permission hook authorizes nothing; never return unfiltered data.\n try {\n if ((await authorize(entry)) === true) visible.push(entry);\n } catch {\n // Denied.\n }\n }\n return visible;\n}\n\n/** Explicit maintenance API. Scheduling and retention window belong to the consumer. */\nexport async function pruneAuditTrail(\n logs: AuditLogCollection,\n options: { maxAgeDays: number; now?: Date; batchSize?: number },\n): Promise<number> {\n const now = options.now ?? new Date();\n const batchSize = options.batchSize ?? 500;\n if (\n !Number.isFinite(options.maxAgeDays) ||\n options.maxAgeDays <= 0 ||\n !Number.isFinite(now.getTime()) ||\n !Number.isSafeInteger(batchSize) ||\n batchSize < 1 ||\n batchSize > 1000\n ) {\n throw new Error(\n 'Audit retention requires a positive age and a batch size from 1 to 1000',\n );\n }\n const before = new Date(now.getTime() - options.maxAgeDays * 86_400_000);\n const rows = await logs.list({\n where: { 'occurredAt <': before },\n orderBy: 'occurredAt ASC',\n limit: batchSize,\n });\n let removed = 0;\n for (const row of rows) {\n if (row.id && (await logs.delete(row.id))) removed += 1;\n }\n return removed;\n}\n","/**\n * MagicLinkToken - Temporary tokens for email verification\n *\n * Stores hashed magic link tokens with expiration. Tokens are single-use\n * and automatically invalidated after verification or expiration.\n */\n\nimport { createHash, randomBytes } from 'node:crypto';\nimport {\n field,\n foreignKey,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { NostrIdentity } from './NostrIdentity';\n\nexport interface MagicLinkTokenOptions extends SmrtObjectOptions {\n nostrIdentityId?: string;\n tokenHash?: string;\n email?: string;\n expiresAt?: Date;\n usedAt?: Date | null;\n requestedFromIp?: string;\n createdAt?: Date;\n}\n\nexport interface GenerateTokenResult {\n /** The plaintext token (only available at creation time) */\n token: string;\n /** The MagicLinkToken record */\n magicLinkToken: MagicLinkToken;\n}\n\n/** Default token expiration: 15 minutes */\nconst DEFAULT_EXPIRATION_MINUTES = 15;\n\n@smrt({\n tableName: 'magic_link_tokens',\n // Carries the login-token hash `verify()` looks up by. Never in the change\n // feed (#2937).\n sensitive: true,\n api: { exclude: ['*'] }, // No API access - internal only\n mcp: { exclude: ['*'] },\n cli: { include: ['list'] }, // Admin visibility only\n})\nexport class MagicLinkToken extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-profiles\";\n /**\n * Link to the NostrIdentity this token is for\n */\n @foreignKey('NostrIdentity', { required: true })\n nostrIdentityId?: string;\n\n /**\n * SHA-256 hash of the token (never store plaintext).\n *\n * Indexed: `verify()` looks tokens up by this hash on every magic-link\n * click (#2364, epic #2382 finding A3).\n */\n @field({ indexed: true })\n tokenHash: string = '';\n\n /**\n * Email this token was sent to\n */\n email: string = '';\n\n /**\n * When this token expires\n */\n expiresAt: Date = new Date(\n Date.now() + DEFAULT_EXPIRATION_MINUTES * 60 * 1000,\n );\n\n /**\n * When this token was used (null = unused)\n */\n usedAt: Date | null = null;\n\n /**\n * IP address that requested the token (for rate limiting)\n */\n requestedFromIp: string = '';\n\n /**\n * When this token was created (for rate limiting)\n */\n createdAt: Date = new Date();\n\n constructor(options: MagicLinkTokenOptions = {}) {\n super(options);\n if (options.nostrIdentityId) this.nostrIdentityId = options.nostrIdentityId;\n if (options.tokenHash) this.tokenHash = options.tokenHash;\n if (options.email) this.email = options.email;\n if (options.expiresAt) this.expiresAt = options.expiresAt;\n if (options.usedAt !== undefined) this.usedAt = options.usedAt;\n if (options.requestedFromIp) this.requestedFromIp = options.requestedFromIp;\n if (options.createdAt) this.createdAt = options.createdAt;\n }\n\n /**\n * Hash a token using SHA-256\n */\n static hashToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n }\n\n /**\n * Generate a new magic link token\n * @param nostrIdentity - The identity this token is for\n * @param email - The email address to send to\n * @param options - Additional options\n */\n static async generate(\n nostrIdentity: NostrIdentity,\n email: string,\n options: {\n expiresInMinutes?: number;\n requestedFromIp?: string;\n db?: SmrtObjectOptions['db'];\n } = {},\n ): Promise<GenerateTokenResult> {\n // Generate 32 bytes of random data (256 bits of entropy)\n const tokenBytes = randomBytes(32);\n const token = tokenBytes.toString('base64url');\n const tokenHash = MagicLinkToken.hashToken(token);\n\n const expiresInMinutes =\n options.expiresInMinutes ?? DEFAULT_EXPIRATION_MINUTES;\n const expiresAt = new Date(Date.now() + expiresInMinutes * 60 * 1000);\n\n const magicLinkToken = new MagicLinkToken({\n db: options.db ?? nostrIdentity.options?.db,\n nostrIdentityId: nostrIdentity.id as string,\n tokenHash,\n email: email.toLowerCase(),\n expiresAt,\n requestedFromIp: options.requestedFromIp || '',\n });\n\n await magicLinkToken.initialize();\n await magicLinkToken.save();\n\n return { token, magicLinkToken };\n }\n\n /**\n * Verify a token and return the MagicLinkToken if valid\n * @param token - The plaintext token to verify\n * @param options - Database options\n * @returns The MagicLinkToken if valid, null otherwise\n */\n static async verify(\n token: string,\n options: SmrtObjectOptions = {},\n ): Promise<MagicLinkToken | null> {\n const tokenHash = MagicLinkToken.hashToken(token);\n\n const { MagicLinkTokenCollection } = await import(\n '../collections/MagicLinkTokenCollection'\n );\n const collection = await MagicLinkTokenCollection.create(options);\n\n const magicLinkToken = await collection.findOne({\n where: { tokenHash },\n });\n\n if (!magicLinkToken) {\n return null;\n }\n\n // Check if valid\n if (!magicLinkToken.isValid()) {\n return null;\n }\n\n return magicLinkToken;\n }\n\n /**\n * Check if this token is valid (not expired and not used)\n */\n isValid(): boolean {\n if (this.usedAt !== null) {\n return false;\n }\n if (new Date() > this.expiresAt) {\n return false;\n }\n return true;\n }\n\n /**\n * Check if this token has expired\n */\n isExpired(): boolean {\n return new Date() > this.expiresAt;\n }\n\n /**\n * Check if this token has been used\n */\n isUsed(): boolean {\n return this.usedAt !== null;\n }\n\n /**\n * Mark this token as used\n */\n async markUsed(): Promise<void> {\n this.usedAt = new Date();\n await this.save();\n }\n\n /**\n * Get the NostrIdentity this token is for\n */\n async getNostrIdentity(): Promise<NostrIdentity | null> {\n return (await this.getRelated('nostrIdentityId')) as NostrIdentity | null;\n }\n\n /**\n * Get time remaining until expiration in seconds\n */\n getTimeRemainingSeconds(): number {\n const now = new Date();\n const diff = this.expiresAt.getTime() - now.getTime();\n return Math.max(0, Math.floor(diff / 1000));\n }\n}\n","/**\n * MagicLinkTokenCollection - Collection for managing magic link tokens\n */\n\nimport { SmrtCollection } from '@happyvertical/smrt-core';\nimport { MagicLinkToken } from '../models/MagicLinkToken';\n\nexport class MagicLinkTokenCollection extends SmrtCollection<MagicLinkToken> {\n static readonly _itemClass = MagicLinkToken;\n\n /**\n * Find token by hash\n */\n async findByTokenHash(tokenHash: string): Promise<MagicLinkToken | null> {\n return await this.findOne({\n where: { tokenHash },\n });\n }\n\n /**\n * Find active (non-expired, non-used) tokens for an email\n */\n async findActiveForEmail(email: string): Promise<MagicLinkToken[]> {\n const tokens = await this.list({\n where: { email: email.toLowerCase() },\n });\n return tokens.filter((token) => token.isValid());\n }\n\n /**\n * Find tokens for a NostrIdentity\n */\n async findByIdentity(nostrIdentityId: string): Promise<MagicLinkToken[]> {\n return await this.list({\n where: { nostrIdentityId },\n });\n }\n\n /**\n * Count tokens created for an email within a time window (for rate limiting)\n * @param email - Email address\n * @param withinMinutes - Time window in minutes\n */\n async countRecentByEmail(\n email: string,\n withinMinutes: number,\n ): Promise<number> {\n const cutoff = new Date(Date.now() - withinMinutes * 60 * 1000);\n const tokens = await this.list({\n where: { email: email.toLowerCase() },\n });\n\n // Filter tokens created after cutoff\n // Note: We use createdAt from SmrtObject base\n return tokens.filter((token) => {\n const createdAt = token.createdAt;\n return createdAt && new Date(createdAt) > cutoff;\n }).length;\n }\n\n /**\n * Count tokens created from an IP within a time window (for rate limiting)\n * @param ip - IP address\n * @param withinMinutes - Time window in minutes\n */\n async countRecentByIp(ip: string, withinMinutes: number): Promise<number> {\n const cutoff = new Date(Date.now() - withinMinutes * 60 * 1000);\n const tokens = await this.list({\n where: { requestedFromIp: ip },\n });\n\n // Filter tokens created after cutoff\n return tokens.filter((token) => {\n const createdAt = token.createdAt;\n return createdAt && new Date(createdAt) > cutoff;\n }).length;\n }\n\n /**\n * Verify a token and return it if valid\n */\n async verify(token: string): Promise<MagicLinkToken | null> {\n const tokenHash = MagicLinkToken.hashToken(token);\n const magicLinkToken = await this.findByTokenHash(tokenHash);\n\n if (!magicLinkToken) {\n return null;\n }\n\n if (!magicLinkToken.isValid()) {\n return null;\n }\n\n return magicLinkToken;\n }\n\n /**\n * Clean up expired tokens by deleting them\n * @returns Number of tokens deleted\n */\n async cleanupExpired(): Promise<number> {\n const now = new Date();\n const allTokens = await this.list({});\n let deleted = 0;\n\n for (const token of allTokens) {\n if (token.isExpired() || token.isUsed()) {\n await token.delete();\n deleted++;\n }\n }\n\n return deleted;\n }\n\n /**\n * Revoke all tokens for a NostrIdentity (e.g., when identity is deleted)\n */\n async revokeForIdentity(nostrIdentityId: string): Promise<number> {\n const tokens = await this.findByIdentity(nostrIdentityId);\n let revoked = 0;\n\n for (const token of tokens) {\n if (!token.isUsed()) {\n await token.markUsed(); // Mark as used to invalidate\n revoked++;\n }\n }\n\n return revoked;\n }\n\n /**\n * Check if rate limit is exceeded for email\n * @param email - Email address\n * @param maxPerHour - Maximum tokens allowed per hour (default: 5)\n */\n async isRateLimitedByEmail(\n email: string,\n maxPerHour: number = 5,\n ): Promise<boolean> {\n const count = await this.countRecentByEmail(email, 60);\n return count >= maxPerHour;\n }\n\n /**\n * Check if rate limit is exceeded for IP\n * @param ip - IP address\n * @param maxPerHour - Maximum tokens allowed per hour (default: 10)\n */\n async isRateLimitedByIp(\n ip: string,\n maxPerHour: number = 10,\n ): Promise<boolean> {\n const count = await this.countRecentByIp(ip, 60);\n return count >= maxPerHour;\n }\n}\n","/**\n * Magic Link Service\n *\n * Handles the magic link authentication flow including:\n * - Token generation and storage\n * - Email sending (via callback)\n * - Token verification\n * - Rate limiting checks\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport { MagicLinkTokenCollection } from '../collections/MagicLinkTokenCollection';\nimport { NostrIdentityCollection } from '../collections/NostrIdentityCollection';\nimport { MagicLinkToken } from '../models/MagicLinkToken';\nimport type { NostrIdentity } from '../models/NostrIdentity';\nimport type { Profile } from '../models/Profile';\nimport { encryptPrivkey, generateNostrKeypair } from './nostrCrypto';\n\nexport interface MagicLinkConfig {\n /** Base URL for magic links (e.g., \"https://example.com\") */\n baseUrl: string;\n /** Path for verification endpoint (default: \"/auth/verify\") */\n verifyPath?: string;\n /** Token expiration in minutes (default: 15) */\n expiresInMinutes?: number;\n /** Maximum tokens per email per hour (default: 5) */\n maxTokensPerEmailPerHour?: number;\n /** Maximum tokens per IP per hour (default: 10) */\n maxTokensPerIpPerHour?: number;\n /** Server master secret for encryption */\n masterSecret: string;\n /** Callback to send the email */\n sendEmail: (to: string, magicLink: string) => Promise<void>;\n /** Database options */\n db: SmrtObjectOptions['db'];\n}\n\nexport interface InitiateResult {\n success: boolean;\n /** The Nostr identity (existing or new) */\n nostrIdentity?: NostrIdentity;\n /** The profile (existing or new) */\n profile?: Profile;\n /** True if a new profile was created */\n created: boolean;\n /** Error message if success is false */\n error?: string;\n /** Error code for programmatic handling */\n errorCode?: 'RATE_LIMITED_EMAIL' | 'RATE_LIMITED_IP' | 'EMAIL_SEND_FAILED';\n}\n\nexport interface VerifyResult {\n success: boolean;\n /** The profile */\n profile?: Profile;\n /** The Nostr identity */\n nostrIdentity?: NostrIdentity;\n /** The decrypted keypair (only on success) */\n keypair?: {\n pubkey: string;\n privkey: string;\n npub: string;\n nsec: string;\n };\n /** Error message if success is false */\n error?: string;\n /** Error code for programmatic handling */\n errorCode?: 'INVALID_TOKEN' | 'EXPIRED_TOKEN' | 'USED_TOKEN' | 'NOT_FOUND';\n}\n\nexport interface MagicLinkService {\n /**\n * Initiate magic link flow - generates token and sends email\n */\n initiate(\n email: string,\n options?: {\n requestedFromIp?: string;\n nip05Username?: string;\n },\n ): Promise<InitiateResult>;\n\n /**\n * Verify a magic link token and return decrypted keypair\n */\n verify(token: string): Promise<VerifyResult>;\n}\n\n/**\n * Create a magic link service instance\n */\nexport function createMagicLinkService(\n config: MagicLinkConfig,\n): MagicLinkService {\n const {\n baseUrl,\n verifyPath = '/auth/verify',\n expiresInMinutes = 15,\n maxTokensPerEmailPerHour = 5,\n maxTokensPerIpPerHour = 10,\n masterSecret,\n sendEmail,\n db,\n } = config;\n\n return {\n async initiate(\n email: string,\n options: {\n requestedFromIp?: string;\n nip05Username?: string;\n } = {},\n ): Promise<InitiateResult> {\n const normalizedEmail = email.toLowerCase().trim();\n const { requestedFromIp, nip05Username } = options;\n\n // Create collections\n const identityCollection = await NostrIdentityCollection.create({ db });\n const tokenCollection = await MagicLinkTokenCollection.create({ db });\n\n // Rate limiting checks\n if (\n await tokenCollection.isRateLimitedByEmail(\n normalizedEmail,\n maxTokensPerEmailPerHour,\n )\n ) {\n return {\n success: false,\n created: false,\n error: 'Too many requests for this email. Please try again later.',\n errorCode: 'RATE_LIMITED_EMAIL',\n };\n }\n\n if (\n requestedFromIp &&\n (await tokenCollection.isRateLimitedByIp(\n requestedFromIp,\n maxTokensPerIpPerHour,\n ))\n ) {\n return {\n success: false,\n created: false,\n error: 'Too many requests from this IP. Please try again later.',\n errorCode: 'RATE_LIMITED_IP',\n };\n }\n\n // Check if identity exists\n let nostrIdentity = await identityCollection.findByEmail(normalizedEmail);\n let profile: Profile | null = null;\n let created = false;\n\n if (!nostrIdentity) {\n // Create new identity and profile\n const { Person } = await import('../models/ProfileTypes');\n const { ProfileTypeCollection } = await import(\n '../collections/ProfileTypeCollection'\n );\n\n // Profile.typeId is a required FK, so resolve (or seed) the canonical\n // 'person' type before creating the profile — otherwise `.save()`\n // fails required-field validation. Mirrors createProfileFromNostr /\n // createProfileFromOidc in resolveIdentity.ts.\n const typeCollection = await ProfileTypeCollection.create({ db });\n let personType = await typeCollection.getBySlug('person');\n if (!personType) {\n const { ProfileType } = await import('../models/ProfileType');\n personType = new ProfileType({\n db,\n slug: 'person',\n name: 'Person',\n description: 'Individual person profile',\n });\n await personType.initialize();\n await personType.save();\n }\n\n // Create a new profile for this user (Person is an STI subclass of Profile)\n profile = new Person({\n db,\n typeId: personType.id as string,\n email: normalizedEmail,\n name: normalizedEmail.split('@')[0], // Default name from email\n });\n await profile.initialize();\n await profile.save();\n\n // Generate keypair and encrypt\n const keypair = generateNostrKeypair();\n const encrypted = encryptPrivkey(keypair.privkey, masterSecret);\n\n // Create Nostr identity\n const { NostrIdentity: NostrIdentityClass } = await import(\n '../models/NostrIdentity'\n );\n nostrIdentity = new NostrIdentityClass({\n db,\n profileId: profile.id!,\n pubkey: keypair.pubkey,\n encryptedPrivkey: encrypted.ciphertext,\n encryptionIv: encrypted.iv,\n encryptionTag: encrypted.tag,\n email: normalizedEmail,\n nip05Username:\n nip05Username?.toLowerCase() || normalizedEmail.split('@')[0],\n });\n await nostrIdentity.initialize();\n await nostrIdentity.save();\n\n created = true;\n } else {\n profile = await nostrIdentity.getProfile();\n }\n\n // Generate magic link token\n const { token } = await MagicLinkToken.generate(\n nostrIdentity,\n normalizedEmail,\n {\n expiresInMinutes,\n requestedFromIp,\n db,\n },\n );\n\n // Build magic link URL\n const magicLink = `${baseUrl}${verifyPath}?token=${encodeURIComponent(token)}`;\n\n // Send email\n try {\n await sendEmail(normalizedEmail, magicLink);\n } catch (emailError) {\n return {\n success: false,\n created,\n nostrIdentity,\n profile: profile || undefined,\n error: 'Failed to send email. Please try again.',\n errorCode: 'EMAIL_SEND_FAILED',\n };\n }\n\n return {\n success: true,\n created,\n nostrIdentity,\n profile: profile || undefined,\n };\n },\n\n async verify(token: string): Promise<VerifyResult> {\n // Verify token\n const magicLinkToken = await MagicLinkToken.verify(token, { db });\n\n if (!magicLinkToken) {\n // Try to get more specific error\n const tokenHash = MagicLinkToken.hashToken(token);\n const tokenCollection = await MagicLinkTokenCollection.create({ db });\n const existingToken = await tokenCollection.findByTokenHash(tokenHash);\n\n if (!existingToken) {\n return {\n success: false,\n error: 'Invalid or expired token.',\n errorCode: 'NOT_FOUND',\n };\n }\n\n if (existingToken.isUsed()) {\n return {\n success: false,\n error: 'This link has already been used.',\n errorCode: 'USED_TOKEN',\n };\n }\n\n if (existingToken.isExpired()) {\n return {\n success: false,\n error: 'This link has expired. Please request a new one.',\n errorCode: 'EXPIRED_TOKEN',\n };\n }\n\n return {\n success: false,\n error: 'Invalid token.',\n errorCode: 'INVALID_TOKEN',\n };\n }\n\n // Mark token as used\n await magicLinkToken.markUsed();\n\n // Get the Nostr identity\n const nostrIdentity = await magicLinkToken.getNostrIdentity();\n if (!nostrIdentity) {\n return {\n success: false,\n error: 'Identity not found.',\n errorCode: 'NOT_FOUND',\n };\n }\n\n // Mark identity as verified\n await nostrIdentity.markVerified();\n\n // Get profile\n const profile = await nostrIdentity.getProfile();\n\n // Decrypt keypair\n const keypair = nostrIdentity.getKeypair(masterSecret);\n\n return {\n success: true,\n profile: profile || undefined,\n nostrIdentity,\n keypair,\n };\n },\n };\n}\n","/**\n * NIP-05 Handler\n *\n * Provides a helper for serving the /.well-known/nostr.json endpoint\n * for NIP-05 identity verification.\n *\n * @see https://github.com/nostr-protocol/nips/blob/master/05.md\n */\n\nimport type { SmrtObjectOptions } from '@happyvertical/smrt-core';\nimport {\n type Nip05Response,\n NostrIdentityCollection,\n} from '../collections/NostrIdentityCollection';\n\nexport interface Nip05HandlerConfig {\n /** Database options */\n db: SmrtObjectOptions['db'];\n /** Optional: Additional relays to include for all users */\n defaultRelays?: string[];\n /** Optional: Cache TTL in seconds (default: 300 = 5 minutes) */\n cacheTtlSeconds?: number;\n}\n\nexport interface Nip05Request {\n /** The 'name' query parameter from the request */\n name?: string | null;\n}\n\nexport interface Nip05HandlerResult {\n /** The NIP-05 response body */\n body: Nip05Response;\n /** Suggested headers for the response */\n headers: Record<string, string>;\n /** HTTP status code */\n status: number;\n}\n\n/**\n * Create a NIP-05 handler\n *\n * @example\n * // SvelteKit\n * import { createNip05Handler } from '@happyvertical/smrt-profiles';\n *\n * const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });\n *\n * export async function GET({ url }) {\n * const result = await handler({ name: url.searchParams.get('name') });\n * return new Response(JSON.stringify(result.body), {\n * status: result.status,\n * headers: result.headers,\n * });\n * }\n *\n * @example\n * // Express\n * import { createNip05Handler } from '@happyvertical/smrt-profiles';\n *\n * const handler = createNip05Handler({ db: { type: 'postgres', url: DATABASE_URL } });\n *\n * app.get('/.well-known/nostr.json', async (req, res) => {\n * const result = await handler({ name: req.query.name });\n * res.status(result.status).set(result.headers).json(result.body);\n * });\n */\nexport function createNip05Handler(config: Nip05HandlerConfig) {\n const { db, defaultRelays = [], cacheTtlSeconds = 300 } = config;\n\n return async function handleNip05Request(\n request: Nip05Request,\n ): Promise<Nip05HandlerResult> {\n const { name } = request;\n\n const collection = await NostrIdentityCollection.create({ db });\n const response = await collection.getNip05Response(name || undefined);\n\n // Add default relays if configured\n if (defaultRelays.length > 0 && Object.keys(response.names).length > 0) {\n response.relays = {};\n for (const pubkey of Object.values(response.names)) {\n response.relays[pubkey] = defaultRelays;\n }\n }\n\n // If specific name requested but not found, return empty names\n if (name && Object.keys(response.names).length === 0) {\n return {\n body: { names: {} },\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': `public, max-age=${cacheTtlSeconds}`,\n },\n status: 200, // NIP-05 spec says return 200 with empty names, not 404\n };\n }\n\n return {\n body: response,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': `public, max-age=${cacheTtlSeconds}`,\n },\n status: 200,\n };\n };\n}\n\n/**\n * Validate a NIP-05 identifier format\n * @param identifier - The identifier to validate (e.g., \"alice@example.com\")\n */\nexport function isValidNip05Identifier(identifier: string): boolean {\n // NIP-05 format: <local-part>@<domain>\n const parts = identifier.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [localPart, domain] = parts;\n\n // Local part: alphanumeric, _, -\n if (!/^[a-z0-9_-]+$/i.test(localPart)) {\n return false;\n }\n\n // Domain: basic domain validation\n if (!/^[a-z0-9.-]+\\.[a-z]{2,}$/i.test(domain)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Parse a NIP-05 identifier into its parts\n * @param identifier - The identifier to parse (e.g., \"alice@example.com\")\n */\nexport function parseNip05Identifier(identifier: string): {\n localPart: string;\n domain: string;\n} | null {\n if (!isValidNip05Identifier(identifier)) {\n return null;\n }\n\n const [localPart, domain] = identifier.split('@');\n return { localPart, domain };\n}\n"],"mappings":"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"}
|