@fload-ai/mcp 0.1.0
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/README.md +359 -0
- package/dist/index.js +5654 -0
- package/dist/index.js.map +7 -0
- package/package.json +56 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/config.ts", "../src/server.ts", "../src/auth.ts", "../../database/src/index.ts", "../../database/src/schema.ts", "../../database/src/schema-timescale.ts", "../../database/src/migrate.ts", "../src/lib/db-client.ts", "../src/rate-limiter.ts", "../src/scopes.ts", "../src/tools/apps.ts", "../src/lib/format.ts", "../src/tools/reviews.ts", "../src/tools/analytics.ts", "../src/tools/agents.ts", "../src/tools/anomalies.ts", "../src/tools/ads.ts", "../src/tools/growth.ts", "../src/tools/forecasting.ts", "../src/tools/dashboard.ts", "../src/tools/actions.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Fload MCP Server\n * Entry point for STDIO transport (Claude Desktop, local agents)\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { loadConfig } from './config.js';\nimport { createMcpServer } from './server.js';\nimport { testConnection } from './lib/db-client.js';\n\nasync function main() {\n try {\n console.error('[Fload MCP] Starting server...');\n\n // Load configuration\n const config = loadConfig();\n console.error('[Fload MCP] Configuration loaded');\n\n // Test database connection\n const dbConnected = await testConnection();\n if (!dbConnected) {\n throw new Error('Database connection failed. Check DATABASE_URL.');\n }\n console.error('[Fload MCP] Database connected');\n\n // Create MCP server\n const server = await createMcpServer(config);\n\n // Create STDIO transport\n const transport = new StdioServerTransport();\n \n // Connect server to transport\n await server.connect(transport);\n\n console.error('[Fload MCP] Server running on stdio');\n console.error('[Fload MCP] Ready to accept tool calls from MCP clients');\n } catch (error) {\n console.error('[Fload MCP] Fatal error:', error);\n process.exit(1);\n }\n}\n\n// Handle graceful shutdown\nprocess.on('SIGINT', () => {\n console.error('[Fload MCP] Received SIGINT, shutting down...');\n process.exit(0);\n});\n\nprocess.on('SIGTERM', () => {\n console.error('[Fload MCP] Received SIGTERM, shutting down...');\n process.exit(0);\n});\n\nmain().catch((error) => {\n console.error('[Fload MCP] Unhandled error:', error);\n process.exit(1);\n});\n", "import 'dotenv/config';\nimport { readFileSync, existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\n/**\n * Configuration for Fload MCP Server\n * Loads API key and database connection from environment or config file\n */\n\nexport interface FloadMcpConfig {\n apiKey: string;\n databaseUrl: string;\n organizationId?: string; // Optional: can be derived from API key\n}\n\n/**\n * Load configuration from environment variables or config file\n * Priority: ENV vars > ~/.fload/config.json > error\n */\nexport function loadConfig(): FloadMcpConfig {\n // Try environment variables first\n const apiKey = process.env.FLOAD_API_KEY;\n const databaseUrl = process.env.DATABASE_URL;\n\n if (apiKey && databaseUrl) {\n return {\n apiKey,\n databaseUrl,\n organizationId: process.env.FLOAD_ORG_ID,\n };\n }\n\n // Try config file\n const configPath = join(homedir(), '.fload', 'config.json');\n if (existsSync(configPath)) {\n try {\n const configData = JSON.parse(readFileSync(configPath, 'utf-8'));\n if (configData.apiKey && configData.databaseUrl) {\n return {\n apiKey: configData.apiKey,\n databaseUrl: configData.databaseUrl,\n organizationId: configData.organizationId,\n };\n }\n } catch (error) {\n console.error('Failed to parse config file:', error);\n }\n }\n\n // Dev mode: allow running without API key for local testing\n if (databaseUrl) {\n console.error('[Fload MCP] No API key set \u2014 running in dev mode (no auth)');\n return {\n apiKey: 'dev-mode',\n databaseUrl,\n organizationId: process.env.FLOAD_ORG_ID,\n };\n }\n\n // Error: no valid config found\n throw new Error(\n 'Fload MCP configuration missing. Set DATABASE_URL environment variable (and optionally FLOAD_API_KEY), or create ~/.fload/config.json'\n );\n}\n\n/**\n * Validate API key format\n * Format: fload_sk_{32 chars}\n */\nexport function isValidApiKey(key: string): boolean {\n return /^fload_sk_[a-zA-Z0-9]{32,}$/.test(key);\n}\n", "/**\n * MCP Server setup for Fload\n * Creates and configures the McpServer instance with all tools\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { validateApiKey, updateApiKeyUsage, hasScope } from './auth.js';\nimport type { AuthContext } from './auth.js';\nimport type { FloadMcpConfig } from './config.js';\nimport { RateLimiter } from './rate-limiter.js';\nimport { getRequiredScope } from './scopes.js';\n\n// Import tools\nimport {\n listAppsSchema,\n listApps,\n getAppDetailsSchema,\n getAppDetails,\n} from './tools/apps.js';\nimport {\n getReviewsSchema,\n getReviews,\n} from './tools/reviews.js';\nimport {\n getAnalyticsSummarySchema,\n getAnalyticsSummary,\n} from './tools/analytics.js';\nimport {\n listAgentsSchema,\n listAgents,\n getAgentDetailsSchema,\n getAgentDetails,\n getAgentRunHistorySchema,\n getAgentRunHistory,\n} from './tools/agents.js';\nimport {\n getAnomaliesSchema,\n getAnomalies,\n} from './tools/anomalies.js';\nimport {\n getAdsPerformanceSchema,\n getAdsPerformance,\n} from './tools/ads.js';\nimport {\n getGrowthAuditSchema,\n getGrowthAudit,\n getGrowthScoreSchema,\n getGrowthScore,\n} from './tools/growth.js';\nimport {\n getForecastsSchema,\n getForecasts,\n} from './tools/forecasting.js';\nimport {\n getDashboardOverviewSchema,\n getDashboardOverview,\n} from './tools/dashboard.js';\nimport {\n listPendingActionsSchema,\n listPendingActions,\n approveActionSchema,\n approveAction,\n rejectActionSchema,\n rejectAction,\n} from './tools/actions.js';\n\n/**\n * Create and configure MCP server\n */\nexport async function createMcpServer(config: FloadMcpConfig): Promise<McpServer> {\n // Validate API key and get auth context\n const authContext = await validateApiKey(config.apiKey);\n\n console.error('[Fload MCP] Server initializing...');\n console.error(`[Fload MCP] Organization: ${authContext.organizationId}`);\n console.error(`[Fload MCP] Scopes: ${authContext.scopes.join(', ')}`);\n\n // Create MCP server instance\n const server = new McpServer({\n name: 'fload',\n version: '0.1.0',\n });\n\n const rateLimiter = new RateLimiter(100, 60_000);\n\n function wrapTool<T>(\n toolName: string,\n handler: (input: T, auth: AuthContext) => Promise<any>\n ) {\n return async (input: T) => {\n // Rate limit check\n const rateCheck = rateLimiter.check(authContext.organizationId);\n if (!rateCheck.allowed) {\n return {\n content: [{\n type: 'text' as const,\n text: `Rate limit exceeded. Try again in ${Math.ceil(rateCheck.retryAfterMs / 1000)}s. Limit: 100 requests/minute.`,\n }],\n isError: true,\n };\n }\n\n // Scope check\n const requiredScope = getRequiredScope(toolName);\n if (requiredScope && !hasScope(authContext, requiredScope)) {\n return {\n content: [{\n type: 'text' as const,\n text: `Permission denied. This tool requires the '${requiredScope}' scope. Your API key has: ${authContext.scopes.join(', ')}`,\n }],\n isError: true,\n };\n }\n\n // Update usage in background\n updateApiKeyUsage(config.apiKey).catch(() => {});\n\n return handler(input, authContext);\n };\n }\n\n // =============================================================================\n // APP TOOLS\n // =============================================================================\n\n server.registerTool(\n 'list_apps',\n {\n description: 'List all mobile apps in your Fload organization. Returns app metadata including name, bundle ID, platform (iOS/Android), icon URL, and category.',\n inputSchema: listAppsSchema.shape,\n },\n wrapTool('list_apps', listApps)\n );\n\n server.registerTool(\n 'get_app_details',\n {\n description: 'Get detailed information about a specific app, including metadata, connected data sources (App Store Connect, Google Play Console), and sync status. Provide either assetId (UUID) or bundleId.',\n inputSchema: getAppDetailsSchema.shape,\n },\n wrapTool('get_app_details', getAppDetails)\n );\n\n // =============================================================================\n // REVIEW TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_reviews',\n {\n description: 'Get app reviews with flexible filtering. Filter by app (assetId or bundleId), platform, rating (1-5 stars), replied status, and date range. Returns reviews with metadata, author, body text, and reply status. Useful for sentiment analysis, support workflows, and review management.',\n inputSchema: getReviewsSchema.shape,\n },\n wrapTool('get_reviews', getReviews)\n );\n\n // =============================================================================\n // ANALYTICS TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_analytics_summary',\n {\n description: 'Get analytics summary with timeseries data for a specific metric. Metrics include downloads, revenue, active_users, sessions, retention, and crashes. Returns summary statistics (total, average, min, max, trend) and timeseries data points. Specify time period (7d, 30d, 90d) and granularity (day, week, month).',\n inputSchema: getAnalyticsSummarySchema.shape,\n },\n wrapTool('get_analytics_summary', getAnalyticsSummary)\n );\n\n // =============================================================================\n // AGENT TOOLS\n // =============================================================================\n\n server.registerTool(\n 'list_agents',\n {\n description: 'List all available AI agents in the Fload platform with their current status. Returns agent types (review, monitoring, forecasting, growth, aso, ads, product, submission_review) and configuration status.',\n inputSchema: listAgentsSchema.shape,\n },\n wrapTool('list_agents', listAgents)\n );\n\n server.registerTool(\n 'get_agent_details',\n {\n description: 'Get detailed configuration and status for a specific agent type. For the review agent, returns per-asset settings (mode, tone, custom instructions). For the product agent, returns latest run details.',\n inputSchema: getAgentDetailsSchema.shape,\n },\n wrapTool('get_agent_details', getAgentDetails)\n );\n\n server.registerTool(\n 'get_agent_run_history',\n {\n description: 'Get run history for a specific agent type. Currently available for the product agent (BrowserStack app installation runs). Returns run status, timing, and error details.',\n inputSchema: getAgentRunHistorySchema.shape,\n },\n wrapTool('get_agent_run_history', getAgentRunHistory)\n );\n\n // =============================================================================\n // ANOMALY TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_anomalies',\n {\n description: 'Get detected anomalies (unusual metric changes) for your apps. Filter by app, severity (low/medium/high/critical), type (surge/decline), status, metric name, and date range. Returns actual vs expected values, deviation percentage, confidence, and suggested actions.',\n inputSchema: getAnomaliesSchema.shape,\n },\n wrapTool('get_anomalies', getAnomalies)\n );\n\n // =============================================================================\n // ADS TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_ads_performance',\n {\n description: 'Get ad campaign performance data across platforms (Apple Search Ads, Google Ads, Meta Ads, TikTok Ads). Returns campaign metadata, status, and for Apple Search Ads includes daily performance snapshots (spend, impressions, taps, installs, CPI, TTR, conversion rate).',\n inputSchema: getAdsPerformanceSchema.shape,\n },\n wrapTool('get_ads_performance', getAdsPerformance)\n );\n\n // =============================================================================\n // GROWTH TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_growth_audit',\n {\n description: 'Get a comprehensive growth audit for an app. Synthesizes data from review sentiment analysis, recent anomalies, valuation trends, and connector health into an actionable growth assessment.',\n inputSchema: getGrowthAuditSchema.shape,\n },\n wrapTool('get_growth_audit', getGrowthAudit)\n );\n\n server.registerTool(\n 'get_growth_score',\n {\n description: 'Get a calculated growth score (0-100) and grade (A-F) for an app. The score is based on app store rating, valuation trend, recent anomalies, review sentiment, and data connector health. Includes a breakdown of scoring factors.',\n inputSchema: getGrowthScoreSchema.shape,\n },\n wrapTool('get_growth_score', getGrowthScore)\n );\n\n // =============================================================================\n // FORECASTING TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_forecasts',\n {\n description: 'Get valuation-based forecasts and trend analysis for an app. Returns historical valuation data points, trend statistics (direction, volatility), and simple linear projections. For detailed metric forecasting with statistical models, use the platform dashboard.',\n inputSchema: getForecastsSchema.shape,\n },\n wrapTool('get_forecasts', getForecasts)\n );\n\n // =============================================================================\n // DASHBOARD TOOLS\n // =============================================================================\n\n server.registerTool(\n 'get_dashboard_overview',\n {\n description: 'Get an aggregated dashboard overview for the organization. Returns portfolio summary (apps, valuations, ratings), data connector health status, and alerts (recent anomalies, pending review drafts).',\n inputSchema: getDashboardOverviewSchema.shape,\n },\n wrapTool('get_dashboard_overview', getDashboardOverview)\n );\n\n // =============================================================================\n // ACTION TOOLS\n // =============================================================================\n\n server.registerTool(\n 'list_pending_actions',\n {\n description: 'List pending actions awaiting approval. Currently shows AI-generated review draft replies that have not been sent yet. Includes the original review context and the drafted reply. Filter by app.',\n inputSchema: listPendingActionsSchema.shape,\n },\n wrapTool('list_pending_actions', listPendingActions)\n );\n\n server.registerTool(\n 'approve_action',\n {\n description: 'Approve a pending action (e.g., a review draft reply). This marks the reply for sending. Optionally edit the reply text before approving.',\n inputSchema: approveActionSchema.shape,\n },\n wrapTool('approve_action', approveAction)\n );\n\n server.registerTool(\n 'reject_action',\n {\n description: 'Reject a pending action (e.g., delete a review draft reply). The draft will be permanently removed.',\n inputSchema: rejectActionSchema.shape,\n },\n wrapTool('reject_action', rejectAction)\n );\n\n const toolCount = 16;\n console.error(`[Fload MCP] Registered ${toolCount} tools`);\n\n return server;\n}\n", "import { createHash } from 'crypto';\nimport { db } from './lib/db-client.js';\nimport { apiKey as apiKeyTable } from '@packages/database';\nimport { eq, isNull, and, or, gt } from 'drizzle-orm';\n\nexport interface AuthContext {\n userId: string;\n organizationId: string;\n scopes: string[];\n}\n\nfunction hashKey(key: string): string {\n return createHash('sha256').update(key).digest('hex');\n}\n\nexport async function validateApiKey(key: string): Promise<AuthContext> {\n // Dev mode bypass\n if (key === 'dev-mode') {\n console.error('[MCP Auth] Running in dev mode (no auth)');\n return {\n userId: 'dev-user',\n organizationId: process.env.FLOAD_ORG_ID || 'dev-org',\n scopes: ['read:apps', 'read:reviews', 'read:analytics'],\n };\n }\n\n const keyHash = hashKey(key);\n\n const record = await db.query.apiKey.findFirst({\n where: and(\n eq(apiKeyTable.keyHash, keyHash),\n isNull(apiKeyTable.revokedAt),\n or(\n isNull(apiKeyTable.expiresAt),\n gt(apiKeyTable.expiresAt, new Date())\n )\n ),\n });\n\n if (!record) {\n throw new Error('Invalid or revoked API key');\n }\n\n // Update lastUsedAt in background (don't await)\n db.update(apiKeyTable)\n .set({ lastUsedAt: new Date() })\n .where(eq(apiKeyTable.id, record.id))\n .then(() => {})\n .catch((err) => console.error('[MCP Auth] Failed to update lastUsedAt:', err));\n\n return {\n userId: record.userId,\n organizationId: record.organizationId,\n scopes: record.scopes,\n };\n}\n\nexport function hasScope(context: AuthContext, requiredScope: string): boolean {\n return context.scopes.includes(requiredScope) || context.scopes.includes('admin:*');\n}\n\nexport async function updateApiKeyUsage(key: string): Promise<void> {\n if (key === 'dev-mode') return;\n\n const keyHash = hashKey(key);\n await db\n .update(apiKeyTable)\n .set({ lastUsedAt: new Date() })\n .where(eq(apiKeyTable.keyHash, keyHash));\n}\n", "import 'dotenv/config';\n\nimport { drizzle } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport * as schema from './schema';\nimport * as timescaleSchema from './schema-timescale';\n\n// Supabase connection\nconst connectionString = process.env.DATABASE_URL;\nif (!connectionString) {\n throw new Error('DATABASE_URL environment variable is required');\n}\n\nconst client = postgres(connectionString, {\n prepare: false,\n max: 20, // Connection pool size - prevent exhaustion\n idle_timeout: 20, // Close idle connections after 20 seconds\n connect_timeout: 10, // Fail fast if can't connect in 10 seconds\n max_lifetime: 60 * 30, // Recycle connections every 30 minutes\n connection: {\n statement_timeout: 30000, // 30 seconds - kill queries that take too long\n },\n});\n\nexport const db = drizzle(client, { schema });\n\n// TigerDB (TimescaleDB) connection\nconst timescaleConnectionString = process.env.TIMESCALE_URL;\nif (!timescaleConnectionString) {\n console.warn('TIMESCALE_URL not set - metrics database unavailable');\n}\n\nconst timescaleClient = timescaleConnectionString\n ? postgres(timescaleConnectionString, {\n prepare: false,\n ssl: timescaleConnectionString.includes('localhost') ? false : 'require', // SSL only for production\n max: 10, // Reduced pool size to prevent exhaustion\n idle_timeout: 20, // Shorter idle timeout to recycle connections faster\n connect_timeout: 10, // Faster connection timeout\n max_lifetime: 60 * 10, // Shorter lifetime (10 minutes) to prevent stale connections\n fetch_types: false, // Skip type parsing for better performance\n transform: {\n undefined: null, // Transform undefined to null\n },\n onnotice: () => {}, // Suppress notices to reduce overhead\n // Note: statement_timeout is set per-query via withTigerDataGuards() in timescale-query-optimizer.ts\n // TimescaleDB Cloud pooler doesn't support it as a connection parameter\n })\n : null;\n\nexport const timescaleDb = timescaleClient\n ? drizzle(timescaleClient, { schema: timescaleSchema })\n : null;\n\n// Export raw postgres client for operations that don't work well through Drizzle\n// (e.g., CALL statements for stored procedures)\nexport const timescaleRawClient = timescaleClient;\n\n// Exports\nexport * from './schema';\nexport type {\n ChatArtifactType,\n ChatConversationType,\n ChatMessageType,\n ChatVoteType,\n} from './schema';\nexport * from './schema-timescale';\nexport { runMigrations } from './migrate';\n", "import { relations, sql } from 'drizzle-orm';\nimport {\n AnyPgColumn,\n bigint,\n boolean,\n date,\n decimal,\n index,\n integer,\n jsonb,\n numeric,\n pgTable,\n primaryKey,\n real,\n serial,\n text,\n timestamp,\n unique,\n uniqueIndex,\n vector,\n} from 'drizzle-orm/pg-core';\n\n// =============================================================================\n// BETTERAUTH TABLES\n// =============================================================================\n\n// BetterAuth core tables\nexport const user = pgTable('user', {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n email: text('email').notNull().unique(),\n emailVerified: boolean('emailVerified').notNull().default(false),\n image: text('image'),\n isAnonymous: boolean('isAnonymous').default(false),\n metadata: text('metadata').default('{}'),\n // Admin plugin fields\n role: text('role').default('user'),\n banned: boolean('banned').default(false),\n banReason: text('banReason'),\n banExpires: timestamp('banExpires'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\nexport const session = pgTable('session', {\n id: text('id').primaryKey(),\n expiresAt: timestamp('expiresAt').notNull(),\n token: text('token').unique(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n ipAddress: text('ipAddress'),\n userAgent: text('userAgent'),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n activeOrganizationId: text('activeOrganizationId').references(\n () => organization.id,\n { onDelete: 'set null' }\n ),\n // Admin plugin field for impersonation\n impersonatedBy: text('impersonatedBy'),\n}).enableRLS();\n\nexport const account = pgTable('account', {\n id: text('id').primaryKey(),\n accountId: text('accountId').notNull(),\n providerId: text('providerId').notNull(),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n accessToken: text('accessToken'),\n refreshToken: text('refreshToken'),\n idToken: text('idToken'),\n accessTokenExpiresAt: timestamp('accessTokenExpiresAt'),\n refreshTokenExpiresAt: timestamp('refreshTokenExpiresAt'),\n scope: text('scope'),\n password: text('password'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\nexport const verification = pgTable('verification', {\n id: text('id').primaryKey(),\n identifier: text('identifier').notNull(),\n value: text('value').notNull(),\n expiresAt: timestamp('expiresAt').notNull(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\n// Organization tables for BetterAuth organization plugin\nexport const organization = pgTable('organization', {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n slug: text('slug').notNull().unique(),\n logo: text('logo'),\n metadata: text('metadata'), // JSON metadata for custom fields (timezone, etc.)\n generatedName: boolean('generatedName').notNull().default(true), // Track if name was auto-generated\n monitoringEnabled: boolean('monitoring_enabled').notNull().default(false), // Track if monitoring is enabled for this org\n asoEnabled: boolean('aso_enabled').notNull().default(false), // Track if ASO agent is enabled for this org\n agentSettings: jsonb('agent_settings').$type<{\n autonomyMode: 'draft' | 'agent';\n overrides: Record<string, 'draft' | 'agent'>; // per action type override\n notifications: {\n channel: 'slack' | 'discord' | 'email';\n draftApprovalTimeout: number; // hours, default 72\n notifyOnAgentAction: boolean; // notify even in agent mode\n };\n }>(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\n// Subscriptions - Stripe subscription tracking\nexport const subscription = pgTable(\n 'subscription',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n stripeCustomerId: text('stripeCustomerId').notNull().unique(),\n stripeSubscriptionId: text('stripeSubscriptionId').unique(),\n stripeProductId: text('stripeProductId'),\n stripePriceId: text('stripePriceId'),\n status: text('status').notNull().default('trialing'), // 'trialing' | 'active' | 'past_due' | 'canceled' | 'unpaid'\n currentPeriodStart: timestamp('currentPeriodStart'),\n currentPeriodEnd: timestamp('currentPeriodEnd'),\n cancelAtPeriodEnd: boolean('cancelAtPeriodEnd').notNull().default(false),\n canceledAt: timestamp('canceledAt'),\n trialStart: timestamp('trialStart'),\n trialEnd: timestamp('trialEnd'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdIdx: index('subscription_organization_id_idx').on(\n table.organizationId\n ),\n stripeCustomerIdx: index('subscription_stripe_customer_idx').on(\n table.stripeCustomerId\n ),\n stripeSubscriptionIdx: index('subscription_stripe_subscription_idx').on(\n table.stripeSubscriptionId\n ),\n statusIdx: index('subscription_status_idx').on(table.status),\n })\n).enableRLS();\n\nexport type SubscriptionType = typeof subscription.$inferInsert;\n\nexport const member = pgTable(\n 'member',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n role: text('role').notNull().default('member'), // 'owner', 'admin', 'member'\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n userIdIdx: index('member_user_id_idx').on(table.userId),\n })\n).enableRLS();\n\nexport const invitation = pgTable('invitation', {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n email: text('email').notNull(),\n role: text('role').notNull().default('member'),\n status: text('status').notNull().default('pending'), // 'pending', 'accepted', 'expired'\n expiresAt: timestamp('expiresAt').notNull(),\n inviterId: text('inviterId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\n// Scraping Accounts - Accounts for scraping Google Play and App Store\nexport const scrapingAccount = pgTable(\n 'scraping_account',\n {\n id: text('id').primaryKey(),\n type: text('type').notNull(), // 'apple' | 'google'\n email: text('email').notNull(),\n encryptedPassword: jsonb('encrypted_password').notNull(), // EncryptedData format\n phone: text('phone').notNull(), // Phone number for 2FA (e.g., '+14156514133')\n proxyPorts: text('proxy_ports')\n .array()\n .notNull()\n .default(sql`'{}'::text[]`), // ISP proxy ports for sticky sessions (e.g., ['8001', '8002'])\n isActive: boolean('is_active').notNull().default(true),\n usageCount: integer('usage_count').notNull().default(0), // Number of times used for scraping\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n typeEmailIdx: index('scraping_account_type_email_idx').on(\n table.type,\n table.email\n ),\n typeActiveIdx: index('scraping_account_type_active_idx').on(\n table.type,\n table.isActive\n ),\n emailIdx: index('scraping_account_email_idx').on(table.email),\n uniqueTypeEmail: unique('scraping_account_type_email_unique').on(\n table.type,\n table.email\n ),\n })\n).enableRLS();\n\n// Anonymous Linking Token - For linking anonymous sessions across contexts (magic links, different browsers)\nexport const anonymousLinkingToken = pgTable('anonymous_linking_token', {\n id: text('id').primaryKey(),\n token: text('token').notNull().unique(),\n anonymousUserId: text('anonymousUserId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n email: text('email'), // Email address to link to (for magic link and registration flows)\n expiresAt: timestamp('expiresAt').notNull(),\n used: boolean('used').notNull().default(false),\n usedAt: timestamp('usedAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n}).enableRLS();\n\n// =============================================================================\n// FLOAD CORE TABLES\n// =============================================================================\n\n// Data Connectors - App Store Connect and Google Play integrations\nexport const dataConnector = pgTable(\n 'data_connector',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId').references(() => organization.id, {\n onDelete: 'cascade',\n }),\n platform: text('platform').notNull(), // 'app_store_connect' | 'google_play' | 'apple_search_ads'\n name: text('name').notNull(),\n encryptedCredentials: jsonb('encryptedCredentials').notNull(), // AES-256 encrypted credentials\n vendorNumber: text('vendorNumber'), // Apple vendor number or Google Play account ID\n appleSearchAdsOrgId: text('appleSearchAdsOrgId'), // Apple Search Ads organization ID\n scrapingAccountEmail: text('scrapingAccountEmail'), // Linked scraping account email\n roles: jsonb('roles').$type<string[]>(), // App Store Connect roles for this connector (e.g., ['ADMIN', 'FINANCE'])\n lastSync: timestamp('lastSync'),\n status: text('status').notNull().default('active'), // 'active' | 'error' | 'paused'\n syncMetadata: jsonb('syncMetadata'), // Last sync details, error logs, etc.\n // Health tracking fields - auto-disable after repeated failures\n consecutiveFailures: integer('consecutiveFailures').notNull().default(0),\n lastSuccessfulSync: timestamp('lastSuccessfulSync'),\n lastFailureReason: text('lastFailureReason'),\n healthStatus: text('healthStatus').notNull().default('healthy'), // 'healthy' | 'degraded' | 'unhealthy' | 'disabled'\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdIdx: index('data_connector_organization_id_idx').on(\n table.organizationId\n ),\n platformIdx: index('data_connector_platform_idx').on(table.platform),\n statusIdx: index('data_connector_status_idx').on(table.status),\n appleSearchAdsOrgIdIdx: index(\n 'data_connector_apple_search_ads_org_id_idx'\n ).on(table.appleSearchAdsOrgId),\n })\n).enableRLS();\n\nexport type DataConnectorType = typeof dataConnector.$inferInsert;\n\n// Apple Search Ads Campaign Snapshot - daily performance data\nexport const asaCampaignSnapshot = pgTable(\n 'asa_campaign_snapshot',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n campaignId: integer('campaignId').notNull(),\n date: date('date').notNull(), // YYYY-MM-DD\n spend: decimal('spend', { precision: 15, scale: 2 }).notNull(),\n impressions: integer('impressions').notNull(),\n taps: integer('taps').notNull(),\n installs: integer('installs').notNull(),\n cpi: decimal('cpi', { precision: 10, scale: 2 }),\n ttr: decimal('ttr', { precision: 5, scale: 2 }), // percentage\n conversionRate: decimal('conversionRate', { precision: 5, scale: 2 }), // percentage\n healthScore: integer('healthScore'), // 0-100\n snapshotData: jsonb('snapshotData'), // Full campaign data from Apple API\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n orgIdIdx: index('asa_campaign_snapshot_org_id_idx').on(table.organizationId),\n campaignIdIdx: index('asa_campaign_snapshot_campaign_id_idx').on(table.campaignId),\n dateIdx: index('asa_campaign_snapshot_date_idx').on(table.date),\n campaignDateUnique: index('asa_campaign_snapshot_campaign_date_unique').on(\n table.campaignId,\n table.date\n ),\n })\n).enableRLS();\n\nexport type AsaCampaignSnapshotType = typeof asaCampaignSnapshot.$inferInsert;\n\n// Assets - Mobile apps that can be valued\nexport const asset = pgTable(\n 'asset',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n bundleId: text('bundleId').notNull(), // com.company.app\n // Cached appIds for fast review queries - populated from assetDataSource\n // These avoid the JOIN to assetDataSource on every review query\n appleAppId: text('appleAppId'), // Apple Adam ID (e.g., \"417071430\") for iOS reviews\n googleAppId: text('googleAppId'), // Google Play package name for Android reviews (future)\n metadata: jsonb('metadata'), // App category, description, icon, etc.\n currentValuation: decimal('currentValuation', { precision: 15, scale: 2 }),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdIdx: index('asset_organization_id_idx').on(table.organizationId),\n bundleIdIdx: index('asset_bundle_id_idx').on(table.bundleId),\n appleAppIdIdx: index('asset_apple_app_id_idx').on(table.appleAppId),\n googleAppIdIdx: index('asset_google_app_id_idx').on(table.googleAppId),\n })\n).enableRLS();\n\nexport const discoveredApp = pgTable('discovered_app', {\n id: text('id').primaryKey(),\n sourcePlatform: text('source_platform').notNull(), // 'app_store_connect' | 'google_play' | future: 'stripe' | 'revenue_cat' etc.\n developerId: text('developer_id'), // Apple issuerId or Google Play developer account ID\n appId: text('app_id'), // Store specific ID (Apple numeric ID / Google play console ID)\n bundleId: text('bundle_id'), // bundle identifier or package name\n name: text('name').notNull(),\n iconUrl: text('icon_url').notNull(),\n category: text('category').notNull(),\n developer: text('developer'),\n version: text('version'),\n formattedPrice: text('formatted_price'),\n fileSizeBytes: text('file_size_bytes'), // Keep as text to avoid bigint issues, store raw string from store\n description: text('description').notNull(),\n rating: decimal('rating', { precision: 4, scale: 2 }), // e.g. 4.85\n ratingCount: integer('rating_count'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n}).enableRLS();\n\n// Asset Info - Cached enhanced metadata from external app stores / sources\nexport const assetInfo = pgTable(\n 'asset_info',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n // Platform-agnostic design\n platform: text('platform'), // 'ios' | 'android' | 'web' - the platform this implementation runs on\n sourcePlatform: text('source_platform').notNull(), // 'app_store_connect' | 'google_play' | 'stripe' | 'manual' - where data comes from\n appId: text('app_id'), // Store specific ID (Apple numeric ID / package name)\n bundleId: text('bundle_id'),\n name: text('name').notNull(),\n iconUrl: text('icon_url').notNull(),\n category: text('category').notNull(),\n developer: text('developer'),\n version: text('version'),\n fileSizeBytes: text('file_size_bytes'), // Keep as text to avoid bigint issues, store raw string from store\n description: text('description').notNull(),\n rating: decimal('rating', { precision: 4, scale: 2 }), // e.g. 4.85\n ratingCount: integer('rating_count'),\n // Availability dates from Apple App Store Connect\n orderableAt: timestamp('orderable_at'), // When app became orderable (from app-info API)\n downloadableAt: timestamp('downloadable_at'), // When app became downloadable (from app-info API)\n lastFetched: timestamp('last_fetched').defaultNow().notNull(),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n assetPlatformIdx: index('asset_info_asset_platform_idx').on(\n table.assetId,\n table.sourcePlatform\n ),\n appIdx: index('asset_info_app_idx').on(table.appId),\n bundleIdx: index('asset_info_bundle_idx').on(table.bundleId),\n })\n).enableRLS();\n\n// Asset Data Sources - Links between assets and data connectors\nexport const assetDataSource = pgTable(\n 'asset_data_source',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n dataConnectorId: text('dataConnectorId')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n appId: text('appId'), // Apple Adam ID or Google Play package name - nullable until invitation accepted\n sku: text('sku'), // App Store SKU or Google Play SKU\n platformMetadata: jsonb('platformMetadata'), // Platform-specific app data\n linkedAt: timestamp('linkedAt').notNull().defaultNow(),\n },\n table => ({\n assetConnectorIdx: index('asset_data_source_asset_connector_idx').on(\n table.assetId,\n table.dataConnectorId\n ),\n appIdx: index('asset_data_source_app_id_idx').on(table.appId),\n dataConnectorIdIdx: index('asset_data_source_data_connector_id_idx').on(\n table.dataConnectorId\n ),\n })\n).enableRLS();\n\n// NOTE: asset_metric and metric_source tables have been removed\n// All metrics data is now stored in TimescaleDB (metric_data_point table)\n\n// Ad Campaigns - Links ad platform campaigns to assets\n// Works for all ad platforms: Apple Search Ads (auto-linked), Meta/Google/TikTok (manually linked)\nexport const adCampaign = pgTable(\n 'ad_campaign',\n {\n id: text('id').primaryKey(),\n dataConnectorId: text('data_connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n\n // Platform campaign ID (from the ad platform)\n platformCampaignId: text('platform_campaign_id').notNull(),\n\n // Campaign info (cached from platform)\n name: text('name').notNull(),\n status: text('status'), // ACTIVE, PAUSED, DELETED, etc.\n objective: text('objective'), // APP_INSTALLS, CONVERSIONS, TRAFFIC, etc.\n dailyBudget: numeric('daily_budget'), // Budget amount (in platform currency)\n budgetCurrency: text('budget_currency'), // Currency code (USD, EUR, etc.)\n\n // Apple Search Ads org ID that owns this campaign (from campaign.orgId in API response)\n // Different campaigns can belong to different Apple orgs under the same API key\n appleOrgId: bigint('apple_org_id', { mode: 'number' }),\n\n // Linking metadata\n linkSource: text('link_source').notNull().default('manual'), // 'auto' (Apple Search Ads) or 'manual' (Meta/Google/TikTok)\n linkedAt: timestamp('linked_at').notNull().defaultNow(),\n\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n // Unique constraint: one campaign per connector (can't link same campaign twice)\n uniqueCampaign: unique('ad_campaign_connector_campaign_unique').on(\n table.dataConnectorId,\n table.platformCampaignId\n ),\n // Index for querying campaigns by asset\n assetIdx: index('ad_campaign_asset_idx').on(table.assetId),\n // Index for querying campaigns by connector\n connectorIdx: index('ad_campaign_connector_idx').on(table.dataConnectorId),\n // Index for querying by platform campaign ID\n platformCampaignIdx: index('ad_campaign_platform_campaign_idx').on(\n table.platformCampaignId\n ),\n })\n).enableRLS();\n\nexport type AdCampaignType = typeof adCampaign.$inferInsert;\nexport type AdCampaignSelect = typeof adCampaign.$inferSelect;\n\n// Ad Keywords - Cached keyword data from Apple Search Ads campaigns\nexport const adKeyword = pgTable(\n 'ad_keyword',\n {\n id: serial('id').primaryKey(),\n adCampaignId: text('ad_campaign_id')\n .notNull()\n .references(() => adCampaign.id, { onDelete: 'cascade' }),\n adGroupId: bigint('ad_group_id', { mode: 'number' }).notNull(),\n adGroupName: text('ad_group_name'),\n platformKeywordId: bigint('platform_keyword_id', { mode: 'number' }).notNull(),\n text: text('text').notNull(),\n matchType: text('match_type').notNull(),\n status: text('status').notNull().default('ACTIVE'),\n bidAmount: numeric('bid_amount'),\n currency: text('currency').default('USD'),\n lastSyncedAt: timestamp('last_synced_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n campaignIdx: index('ad_keyword_campaign_idx').on(table.adCampaignId),\n uniqueKeyword: unique('ad_keyword_campaign_platform_unique').on(\n table.adCampaignId,\n table.platformKeywordId\n ),\n })\n).enableRLS();\n\nexport type AdKeywordInsert = typeof adKeyword.$inferInsert;\nexport type AdKeywordSelect = typeof adKeyword.$inferSelect;\n\n// Ad Keyword Metrics - Daily performance metrics for keywords\nexport const adKeywordMetric = pgTable(\n 'ad_keyword_metric',\n {\n id: serial('id').primaryKey(),\n adKeywordId: integer('ad_keyword_id')\n .notNull()\n .references(() => adKeyword.id, { onDelete: 'cascade' }),\n date: date('date').notNull(),\n impressions: integer('impressions').default(0),\n taps: integer('taps').default(0),\n installs: integer('installs').default(0),\n spend: numeric('spend').default('0'),\n avgCPI: numeric('avg_cpi'),\n avgCPT: numeric('avg_cpt'),\n ttr: numeric('ttr'),\n conversionRate: numeric('conversion_rate'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n keywordIdx: index('ad_keyword_metric_keyword_idx').on(table.adKeywordId),\n uniqueMetric: unique('ad_keyword_metric_keyword_date_unique').on(\n table.adKeywordId,\n table.date\n ),\n })\n).enableRLS();\n\nexport type AdKeywordMetricInsert = typeof adKeywordMetric.$inferInsert;\nexport type AdKeywordMetricSelect = typeof adKeywordMetric.$inferSelect;\n\n// Ad Search Terms - Search term report data from Apple Search Ads\nexport const adSearchTerm = pgTable(\n 'ad_search_term',\n {\n id: serial('id').primaryKey(),\n adCampaignId: text('ad_campaign_id')\n .notNull()\n .references(() => adCampaign.id, { onDelete: 'cascade' }),\n text: text('text').notNull(),\n impressions: integer('impressions').default(0),\n taps: integer('taps').default(0),\n installs: integer('installs').default(0),\n spend: numeric('spend').default('0'),\n avgCPI: numeric('avg_cpi'),\n reportStartDate: date('report_start_date').notNull(),\n reportEndDate: date('report_end_date').notNull(),\n lastSyncedAt: timestamp('last_synced_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),\n },\n (table) => ({\n campaignIdx: index('ad_search_term_campaign_idx').on(table.adCampaignId),\n uniqueTerm: unique('ad_search_term_campaign_text_dates_unique').on(\n table.adCampaignId,\n table.text,\n table.reportStartDate,\n table.reportEndDate\n ),\n })\n).enableRLS();\n\nexport type AdSearchTermInsert = typeof adSearchTerm.$inferInsert;\nexport type AdSearchTermSelect = typeof adSearchTerm.$inferSelect;\n\n// Valuation History - Track valuations over time\nexport const valuationHistory = pgTable(\n 'valuation_history',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n valuation: decimal('valuation', { precision: 15, scale: 2 }).notNull(),\n baseValuation: decimal('baseValuation', { precision: 15, scale: 2 }),\n calculationMethod: text('calculationMethod').notNull(), // Algorithm version\n calculationDetails: jsonb('calculationDetails').notNull(), // Inputs and factors used\n confidenceScore: decimal('confidenceScore', { precision: 3, scale: 2 }),\n calculatedAt: timestamp('calculatedAt').notNull().defaultNow(),\n\n // Time period references for unified valuation system\n year: integer('year'),\n month: integer('month'),\n week: date('week'), // Week start date for weekly valuations (NULL for monthly)\n assetMetricId: text('asset_metric_id'), // No FK - uses TimescaleDB IDs now\n dataQualityScore: decimal('data_quality_score', { precision: 3, scale: 2 }),\n },\n table => ({\n assetCalculatedIdx: index('valuation_history_asset_calculated_idx').on(\n table.assetId,\n table.calculatedAt\n ),\n assetWeekIdx: index('valuation_history_asset_week_idx').on(\n table.assetId,\n table.week\n ),\n assetYearMonthIdx: index('valuation_history_asset_year_month_idx').on(\n table.assetId,\n table.year,\n table.month\n ),\n })\n).enableRLS();\n\n// NOTE: portfolio and portfolio_asset tables have been removed (unused)\n\n// Review Agent Settings - Per-asset settings for the AI review agent\nexport const reviewAgentSettings = pgTable(\n 'review_agent_settings',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .unique()\n .references(() => asset.id, { onDelete: 'cascade' }),\n // Core settings\n supportEmail: text('supportEmail'),\n teamName: text('teamName'), // How to sign off replies (e.g., \"The Mindfulness App Team\")\n tone: text('tone').default('professional'), // 'professional' | 'friendly' | 'casual'\n // Custom instructions for the AI\n customInstructions: text('customInstructions'), // e.g., \"Never offer refunds\", \"Mention new features\"\n // Agent Mode: 'full_agentic' | 'manual' | 'inactive'\n // full_agentic: Auto-draft AND auto-send replies (default)\n // manual: Auto-draft replies but don't send (user reviews and sends manually)\n // inactive: Just sync reviews, no drafting or sending\n agentMode: text('agent_mode').default('full_agentic'),\n // Deprecated: use agentMode instead\n autoGenerateDrafts: boolean('autoGenerateDrafts').default(false),\n includeAppVersion: boolean('includeAppVersion').default(true), // Mention app version in responses\n // Status\n isOnboarded: boolean('isOnboarded').notNull().default(false),\n // Track which platforms have been onboarded (for multi-platform assets)\n // When a user adds Android after iOS, we can show \"Android Reviews are now here!\"\n onboardedPlatforms: jsonb('onboarded_platforms')\n .$type<('ios' | 'android')[]>()\n .notNull()\n .default([]),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n assetIdx: index('review_agent_settings_asset_idx').on(table.assetId),\n })\n).enableRLS();\n\n// =============================================================================\n// REVIEW STORAGE TABLES\n// =============================================================================\n\n// Reviews - Stored reviews from App Store Connect\nexport const review = pgTable(\n 'review',\n {\n // Use Apple's/Google's review ID as primary key (it's unique per app)\n id: text('id').primaryKey(), // Review ID as string (Apple review ID or Google UUID)\n\n // App identification - appId can be Apple Adam ID or Google Play numeric app ID\n appId: text('app_id').notNull(),\n\n // Platform: 'ios' for App Store, 'android' for Google Play\n platform: text('platform').notNull().default('ios'),\n\n // Review content\n rating: integer('rating').notNull(), // 1-5\n title: text('title').notNull(), // iOS has titles, Android uses empty string\n body: text('body').notNull(), // The actual review text\n nickname: text('nickname').notNull(), // Reviewer's nickname/name\n\n // Metadata for filtering\n storeFront: text('store_front').notNull(), // iOS: 'USA', 'GBR', Android: language code 'en', 'es'\n appVersionString: text('app_version_string').notNull(), // e.g., '2.1.0'\n lastModified: timestamp('last_modified').notNull(), // When review was created/updated\n\n // Engagement metrics (iOS-specific, 0 for Android)\n helpfulViews: integer('helpful_views').notNull().default(0),\n totalViews: integer('total_views').notNull().default(0),\n edited: boolean('edited').notNull().default(false),\n\n // Developer response (stored as JSON for flexibility)\n developerResponse: jsonb('developer_response').$type<{\n responseId: string;\n response: string;\n lastModified: number;\n isHidden: boolean;\n pendingState: string | null;\n } | null>(),\n\n // Editability flag (iOS-specific, always true for Android)\n isEditable: boolean('is_editable').notNull().default(false),\n\n // Timestamps\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n // Primary index for queries - by appId\n appIdx: index('review_app_id_idx').on(table.appId),\n appRatingIdx: index('review_app_rating_idx').on(table.appId, table.rating),\n appStoreFrontIdx: index('review_app_store_front_idx').on(\n table.appId,\n table.storeFront\n ),\n appVersionIdx: index('review_app_version_idx').on(\n table.appId,\n table.appVersionString\n ),\n // Composite index for sorting by date (used in ORDER BY last_modified DESC)\n appLastModifiedIdx: index('review_app_last_modified_idx').on(\n table.appId,\n table.lastModified\n ),\n // Platform index for filtering by store\n appPlatformIdx: index('review_app_platform_idx').on(\n table.appId,\n table.platform\n ),\n // Standalone index on last_modified for sorting queries\n lastModifiedIdx: index('review_last_modified_idx').on(table.lastModified),\n })\n).enableRLS();\n\nexport type ReviewType = typeof review.$inferInsert;\nexport type ReviewSelect = typeof review.$inferSelect;\n\n// Review Draft Replies - Store AI-generated draft replies before they're published\nexport const reviewDraftReply = pgTable(\n 'review_draft_reply',\n {\n id: text('id').primaryKey(),\n reviewId: text('review_id')\n .notNull()\n .unique()\n .references(() => review.id, { onDelete: 'cascade' }),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n\n // Draft reply content\n reply: text('reply').notNull(),\n // Original AI-generated reply (preserved when user edits, used for learning rules)\n originalAiReply: text('original_ai_reply'),\n\n // AI generation metadata\n model: text('model'),\n promptTokens: integer('prompt_tokens'),\n completionTokens: integer('completion_tokens'),\n totalTokens: integer('total_tokens'),\n\n // Batch send tracking\n pendingSendAt: timestamp('pending_send_at'), // When marked for sending (null = draft only)\n sentAt: timestamp('sent_at'), // When successfully sent (null = not sent yet)\n sendAttempts: integer('send_attempts').notNull().default(0), // Retry tracking\n lastSendError: text('last_send_error'), // Last failure reason\n\n // Timestamps\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n assetIdx: index('review_draft_reply_asset_id_idx').on(table.assetId),\n pendingSendIdx: index('review_draft_reply_pending_send_idx').on(\n table.pendingSendAt\n ),\n // Composite index for efficient send_pending queries\n pendingSendCompIdx: index('review_draft_reply_pending_composite_idx').on(\n table.pendingSendAt,\n table.sentAt,\n table.sendAttempts\n ),\n })\n).enableRLS();\n\nexport type ReviewDraftReplyType = typeof reviewDraftReply.$inferInsert;\nexport type ReviewDraftReplySelect = typeof reviewDraftReply.$inferSelect;\n\n// Review History - Snapshots of review state before updates (for tracking edits)\nexport const reviewHistory = pgTable(\n 'review_history',\n {\n id: text('id').primaryKey(),\n reviewId: text('review_id')\n .notNull()\n .references(() => review.id, { onDelete: 'cascade' }),\n\n // Snapshot of review at this point in time\n rating: integer('rating').notNull(), // 1-5\n title: text('title').notNull(),\n body: text('body').notNull(),\n nickname: text('nickname').notNull(),\n storeFront: text('store_front').notNull(),\n appVersionString: text('app_version_string'),\n lastModified: timestamp('last_modified').notNull(), // Original timestamp from Apple/Google\n edited: boolean('edited').notNull().default(false),\n\n // Snapshot of developer response at this time (if any)\n developerResponse: jsonb('developer_response').$type<{\n responseId: string;\n response: string;\n lastModified: number;\n } | null>(),\n\n // Snapshot of draft reply at this time (if any)\n draftReply: jsonb('draft_reply').$type<{\n reply: string;\n createdAt: string; // ISO timestamp\n source: 'ai' | 'user_edited';\n } | null>(),\n\n // Metadata\n capturedAt: timestamp('captured_at').notNull().defaultNow(), // When we captured this snapshot\n },\n table => ({\n // Index for fetching history of a review\n reviewIdx: index('review_history_review_id_idx').on(table.reviewId),\n // Composite index for ordered history queries\n reviewCapturedIdx: index('review_history_review_captured_idx').on(\n table.reviewId,\n table.capturedAt\n ),\n })\n).enableRLS();\n\nexport type ReviewHistoryType = typeof reviewHistory.$inferInsert;\nexport type ReviewHistorySelect = typeof reviewHistory.$inferSelect;\n\n// Review Sync State - Track sync progress per asset\nexport const reviewSyncState = pgTable(\n 'review_sync_state',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .unique()\n .references(() => asset.id, { onDelete: 'cascade' }),\n\n // Watermark: the most recent review ID we've seen per platform\n // When syncing, we stop when we hit this ID\n // DEPRECATED: Use platform-specific watermarks below\n lastSyncedReviewId: text('last_synced_review_id'),\n // Platform-specific watermarks (iOS and Android have different review ID formats)\n lastSyncedReviewIdIos: text('last_synced_review_id_ios'),\n lastSyncedReviewIdAndroid: text('last_synced_review_id_android'),\n\n // Sync status per platform\n isInitialSyncComplete: boolean('is_initial_sync_complete')\n .notNull()\n .default(false),\n isInitialSyncCompleteIos: boolean('is_initial_sync_complete_ios')\n .notNull()\n .default(false),\n isInitialSyncCompleteAndroid: boolean('is_initial_sync_complete_android')\n .notNull()\n .default(false),\n lastSyncedAt: timestamp('last_synced_at'),\n lastSyncError: text('last_sync_error'),\n\n // Stats\n totalReviewsStored: integer('total_reviews_stored').notNull().default(0),\n\n // Progress tracking for active sync\n // DEPRECATED: Use platform-specific flags below\n syncInProgress: boolean('sync_in_progress').notNull().default(false),\n // Platform-specific sync in progress flags\n syncInProgressIos: boolean('sync_in_progress_ios').notNull().default(false),\n syncInProgressAndroid: boolean('sync_in_progress_android').notNull().default(false),\n totalReviewsToSync: integer('total_reviews_to_sync'),\n reviewsSyncedSoFar: integer('reviews_synced_so_far').notNull().default(0),\n\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n assetIdx: index('review_sync_state_asset_idx').on(table.assetId),\n })\n).enableRLS();\n\nexport type ReviewSyncStateType = typeof reviewSyncState.$inferInsert;\nexport type ReviewSyncStateSelect = typeof reviewSyncState.$inferSelect;\n\n// Review Activity Log - Real-time tracking of review processing for live UI updates\n// Used for the agentic experience: animations, typewriter effects, status transitions\nexport const reviewActivityLog = pgTable(\n 'review_activity_log',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n reviewId: text('review_id'), // null for general events like \"sync started\"\n\n // Activity types:\n // - 'synced': New review synced from App Store\n // - 'draft_started': AI draft generation started\n // - 'draft_completed': AI draft generation completed (draftText contains the reply)\n // - 'send_started': Reply submission started\n // - 'sent': Reply successfully published\n // - 'send_failed': Reply submission failed\n activityType: text('activity_type').notNull(),\n\n // For typewriter effect - the full draft text (only for draft_completed)\n draftText: text('draft_text'),\n\n // Human-readable status message\n message: text('message'),\n\n createdAt: timestamp('created_at').notNull().defaultNow(),\n },\n table => ({\n // Index for efficient polling by asset and time\n assetTimeIdx: index('review_activity_log_asset_time_idx').on(\n table.assetId,\n table.createdAt\n ),\n })\n).enableRLS();\n\nexport type ReviewActivityLogType = typeof reviewActivityLog.$inferInsert;\nexport type ReviewActivityLogSelect = typeof reviewActivityLog.$inferSelect;\n\n// Learned Rules - Rules extracted from user edits to AI-generated replies\n// Used to improve future AI responses by learning from user preferences\nexport const learnedRule = pgTable(\n 'learned_rule',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n\n // The extracted rule (imperative instruction for the AI)\n rule: text('rule').notNull(),\n\n // Source context for debugging/transparency\n sourceReviewId: text('source_review_id').references(() => review.id, {\n onDelete: 'set null',\n }),\n originalReply: text('original_reply').notNull(), // AI-generated\n editedReply: text('edited_reply').notNull(), // User-modified\n\n // State\n isActive: boolean('is_active').notNull().default(true),\n appliedCount: integer('applied_count').notNull().default(0), // Track usage\n\n // Timestamps\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n assetIdx: index('learned_rule_asset_id_idx').on(table.assetId),\n activeIdx: index('learned_rule_active_idx').on(table.assetId, table.isActive),\n })\n).enableRLS();\n\nexport type LearnedRuleType = typeof learnedRule.$inferInsert;\nexport type LearnedRuleSelect = typeof learnedRule.$inferSelect;\n\n// Rating Summary - Daily snapshots of rating counts and averages\n// Ratings are separate from reviews: users can rate without writing a review\nexport const ratingSummary = pgTable(\n 'rating_summary',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n appId: text('app_id').notNull(), // Apple Adam ID or Google Play numeric app ID\n\n // Platform: 'ios' for App Store Connect, 'android' for Google Play\n platform: text('platform').notNull().default('ios'),\n\n // The date this snapshot was captured (stored as date, not timestamp)\n date: date('date').notNull(),\n\n // Rating counts\n ratingCount: integer('rating_count').notNull(), // Total ratings\n ratingOneCount: integer('rating_one_count').notNull(),\n ratingTwoCount: integer('rating_two_count').notNull(),\n ratingThreeCount: integer('rating_three_count').notNull(),\n ratingFourCount: integer('rating_four_count').notNull(),\n ratingFiveCount: integer('rating_five_count').notNull(),\n\n // Computed average from store\n averageRating: decimal('average_rating', {\n precision: 5,\n scale: 3,\n }).notNull(),\n\n // Review count (reviews with text, subset of ratings)\n reviewCount: integer('review_count').notNull(),\n\n // Ratings reset info (when Apple last reset ratings, e.g., after major update)\n // Note: Google Play doesn't have ratings reset, this field is iOS-specific\n ratingsResetDate: timestamp('ratings_reset_date'),\n ratingsResetAppVersion: text('ratings_reset_app_version'),\n\n // Timestamps\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n // Unique constraint: one snapshot per asset per platform per day\n assetPlatformDateUnique: uniqueIndex(\n 'rating_summary_asset_platform_date_unique'\n ).on(table.assetId, table.platform, table.date),\n // Index for querying by app\n appIdx: index('rating_summary_app_id_idx').on(table.appId),\n // Index for time-series queries\n assetDateIdx: index('rating_summary_asset_date_idx').on(\n table.assetId,\n table.date\n ),\n // Index for platform filtering\n assetPlatformIdx: index('rating_summary_asset_platform_idx').on(\n table.assetId,\n table.platform\n ),\n })\n).enableRLS();\n\nexport type RatingSummaryType = typeof ratingSummary.$inferInsert;\nexport type RatingSummarySelect = typeof ratingSummary.$inferSelect;\n\n// Webhook Events - Store raw webhook payloads for audit trail and resumability\nexport const webhookEvent = pgTable(\n 'webhook_event',\n {\n id: text('id').primaryKey(),\n source: text('source').notNull(), // 'gmail' | 'twilio' | 'stripe' | etc.\n // Email-specific fields (for gmail source)\n fromEmail: text('fromEmail'), // Sender email address\n toEmail: text('toEmail'), // Recipient email address\n subject: text('subject'), // Email subject\n // Raw payload storage\n headers: jsonb('headers'), // Raw headers object\n bodyPlain: text('bodyPlain'), // Plain text body\n bodyHtml: text('bodyHtml'), // HTML body\n rawPayload: jsonb('rawPayload'), // Full raw payload for non-email webhooks\n // Processing status\n status: text('status').notNull().default('received'), // 'received' | 'processing' | 'processed' | 'failed' | 'skipped'\n processedAt: timestamp('processedAt'),\n errorMessage: text('errorMessage'),\n // Extracted data (for quick lookups without re-parsing)\n extractedData: jsonb('extractedData'), // { acceptanceUrl, providerName, secretCode, etc. }\n // Timestamps\n receivedAt: timestamp('receivedAt').notNull().defaultNow(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n sourceIdx: index('webhook_event_source_idx').on(table.source),\n statusIdx: index('webhook_event_status_idx').on(table.status),\n toEmailIdx: index('webhook_event_to_email_idx').on(table.toEmail),\n fromEmailIdx: index('webhook_event_from_email_idx').on(table.fromEmail),\n receivedAtIdx: index('webhook_event_received_at_idx').on(table.receivedAt),\n })\n).enableRLS();\n\n// RevenueCat webhook events - dedicated idempotent storage\nexport const revenuecatWebhookEvent = pgTable(\n 'revenuecat_webhook_event',\n {\n id: text('id').primaryKey(),\n connectorId: text('connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n eventId: text('event_id').notNull(), // RevenueCat webhook event.id\n eventType: text('event_type').notNull(),\n appUserId: text('app_user_id'),\n originalAppUserId: text('original_app_user_id'),\n payload: jsonb('payload').notNull(),\n status: text('status').notNull().default('received'), // received | processed | failed\n processedAt: timestamp('processed_at'),\n errorMessage: text('error_message'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('revenuecat_webhook_event_connector_idx').on(\n table.connectorId\n ),\n orgIdx: index('revenuecat_webhook_event_org_idx').on(table.organizationId),\n eventIdIdx: uniqueIndex('revenuecat_webhook_event_event_id_unique').on(\n table.eventId\n ),\n appUserIdx: index('revenuecat_webhook_event_app_user_idx').on(\n table.appUserId\n ),\n createdAtIdx: index('revenuecat_webhook_event_created_at_idx').on(\n table.createdAt\n ),\n })\n).enableRLS();\n\nexport const revenuecatCustomer = pgTable(\n 'revenuecat_customer',\n {\n id: text('id').primaryKey(),\n connectorId: text('connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n customerId: text('customer_id').notNull(),\n originalAppUserId: text('original_app_user_id'),\n aliases: jsonb('aliases').$type<string[]>().default(sql`'[]'::jsonb`),\n attributes: jsonb('attributes'),\n firstSeenAt: timestamp('first_seen_at'),\n lastSeenAt: timestamp('last_seen_at'),\n activeEntitlements: jsonb('active_entitlements'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('revenuecat_customer_connector_idx').on(table.connectorId),\n orgIdx: index('revenuecat_customer_org_idx').on(table.organizationId),\n customerIdx: uniqueIndex('revenuecat_customer_connector_customer_unique').on(\n table.connectorId,\n table.customerId\n ),\n originalUserIdx: index('revenuecat_customer_original_user_idx').on(\n table.originalAppUserId\n ),\n })\n).enableRLS();\n\nexport const revenuecatTransaction = pgTable(\n 'revenuecat_transaction',\n {\n id: text('id').primaryKey(),\n connectorId: text('connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n customerId: text('customer_id').notNull(),\n webhookEventId: text('webhook_event_id').references(\n () => revenuecatWebhookEvent.id,\n {\n onDelete: 'set null',\n }\n ),\n storeTransactionId: text('store_transaction_id'),\n originalStoreTransactionId: text('original_store_transaction_id'),\n productId: text('product_id'),\n entitlementIds: jsonb('entitlement_ids').$type<string[] | null>(),\n store: text('store'),\n environment: text('environment'),\n eventType: text('event_type'),\n periodType: text('period_type'),\n purchasedAt: timestamp('purchased_at'),\n expiresAt: timestamp('expires_at'),\n priceUsd: decimal('price_usd', { precision: 15, scale: 4 }),\n priceInPurchasedCurrency: decimal('price_in_purchased_currency', {\n precision: 15,\n scale: 4,\n }),\n purchasedCurrency: text('purchased_currency'),\n taxPercentage: decimal('tax_percentage', { precision: 7, scale: 4 }),\n commissionPercentage: decimal('commission_percentage', {\n precision: 7,\n scale: 4,\n }),\n renewalNumber: integer('renewal_number'),\n isTrialConversion: boolean('is_trial_conversion'),\n isSandbox: boolean('is_sandbox'),\n rawPayload: jsonb('raw_payload'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('revenuecat_transaction_connector_idx').on(\n table.connectorId\n ),\n orgIdx: index('revenuecat_transaction_org_idx').on(table.organizationId),\n customerIdx: index('revenuecat_transaction_customer_idx').on(table.customerId),\n storeTxIdx: index('revenuecat_transaction_store_tx_idx').on(\n table.storeTransactionId\n ),\n purchasedAtIdx: index('revenuecat_transaction_purchased_at_idx').on(\n table.purchasedAt\n ),\n txUnique: uniqueIndex('revenuecat_transaction_unique').on(\n table.connectorId,\n table.storeTransactionId,\n table.renewalNumber\n ),\n })\n).enableRLS();\n\nexport const revenuecatEntitlementState = pgTable(\n 'revenuecat_entitlement_state',\n {\n id: text('id').primaryKey(),\n connectorId: text('connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n customerId: text('customer_id').notNull(),\n entitlementId: text('entitlement_id').notNull(),\n productId: text('product_id'),\n status: text('status').notNull(), // active | expired | billing_issue | paused\n expiresAt: timestamp('expires_at'),\n gracePeriodExpiresAt: timestamp('grace_period_expires_at'),\n lastEventId: text('last_event_id'),\n lastEventType: text('last_event_type'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('revenuecat_entitlement_state_connector_idx').on(\n table.connectorId\n ),\n orgIdx: index('revenuecat_entitlement_state_org_idx').on(table.organizationId),\n customerIdx: index('revenuecat_entitlement_state_customer_idx').on(\n table.customerId\n ),\n entitlementUnique: uniqueIndex('revenuecat_entitlement_state_unique').on(\n table.connectorId,\n table.customerId,\n table.entitlementId\n ),\n })\n).enableRLS();\n\nexport const revenuecatSyncCheckpoint = pgTable(\n 'revenuecat_sync_checkpoint',\n {\n id: text('id').primaryKey(),\n connectorId: text('connector_id')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n checkpointType: text('checkpoint_type').notNull(), // export | webhook | reconcile\n cursor: text('cursor'),\n lastProcessedAt: timestamp('last_processed_at'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('revenuecat_sync_checkpoint_connector_idx').on(\n table.connectorId\n ),\n orgIdx: index('revenuecat_sync_checkpoint_org_idx').on(table.organizationId),\n checkpointUnique: uniqueIndex('revenuecat_sync_checkpoint_unique').on(\n table.connectorId,\n table.checkpointType\n ),\n })\n).enableRLS();\n\n// Platform Invitations - Track invitations to external accounts for scraping\nexport const platformInvitation = pgTable(\n 'platform_invitation',\n {\n id: text('id').primaryKey(),\n dataConnectorId: text('dataConnectorId').references(\n () => dataConnector.id,\n { onDelete: 'cascade' }\n ),\n webhookEventId: text('webhookEventId').references(() => webhookEvent.id, {\n onDelete: 'set null',\n }), // Link to the webhook that triggered this invitation\n developerId: text('developerId'), // Apple teamId or Google Play developer account ID - nullable until invitation accepted\n developerName: text('developerName'), // Provider/Developer name for matching webhooks\n platform: text('platform').notNull(), // 'app_store_connect' | 'google_play' | 'apple_search_ads'\n invitedEmail: text('invitedEmail').notNull(),\n status: text('status').notNull().default('waiting_for_invitation'), // 'waiting_for_invitation' | 'invited' | 'ready' | 'disconnected' | 'expired' | 'invalid' | 'already_accepted' | 'max_providers' | 'failed'\n acceptanceUrl: text('acceptanceUrl'), // URL from webhook to accept invitation - saved for retries\n secretCode: text('secretCode'), // Secret code for Apple Search Ads invitations - saved for retries\n debugScreenshotPath: text('debugScreenshotPath'), // R2 path to debug screenshot captured on failure\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('platform_invitation_connector_idx').on(\n table.dataConnectorId\n ),\n webhookEventIdx: index('platform_invitation_webhook_event_idx').on(\n table.webhookEventId\n ),\n developerIdx: index('platform_invitation_developer_idx').on(\n table.developerId\n ),\n statusIdx: index('platform_invitation_status_idx').on(table.status),\n platformEmailIdx: index('platform_invitation_platform_email_idx').on(\n table.platform,\n table.invitedEmail\n ),\n developerPlatformEmailIdx: index(\n 'platform_invitation_developer_platform_email_idx'\n ).on(table.developerId, table.platform, table.invitedEmail),\n })\n).enableRLS();\n\n// Connector Diagnostic Run - Stores diagnostic run history for connector doctor\nexport const connectorDiagnosticRun = pgTable(\n 'connector_diagnostic_run',\n {\n id: text('id').primaryKey(),\n connectorId: text('connectorId')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n triggeredBy: text('triggeredBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n triggerSource: text('triggerSource').notNull(),\n diagnosis: jsonb('diagnosis').notNull(),\n actionsTaken: jsonb('actionsTaken'),\n connectorSnapshot: jsonb('connectorSnapshot'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n connectorIdx: index('connector_diagnostic_run_connector_idx').on(\n table.connectorId\n ),\n orgIdx: index('connector_diagnostic_run_org_idx').on(\n table.organizationId\n ),\n createdAtIdx: index('connector_diagnostic_run_created_at_idx').on(\n table.createdAt\n ),\n })\n).enableRLS();\n\n// Google Service Account Pool - Pooled SAs for Google Play connectors (max 9 orgs per SA)\nexport const googleServiceAccountPool = pgTable(\n 'google_service_account_pool',\n {\n id: text('id').primaryKey(),\n name: text('name').notNull().unique(), // Cute name: 'kira', 'luna', etc.\n email: text('email').notNull().unique(), // Full email: fload-play-kira@fload-connector.iam.gserviceaccount.com\n encryptedCredentials: jsonb('encryptedCredentials').notNull(), // EncryptedData with GoogleJWTInput\n usageCount: integer('usageCount').notNull().default(0), // Current orgs using this SA\n maxUsage: integer('maxUsage').notNull().default(9), // Max orgs allowed (buffer from 10 limit)\n status: text('status').notNull().default('active'), // 'active' | 'full' | 'disabled'\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n statusUsageIdx: index('gsa_pool_status_usage_idx').on(\n table.status,\n table.usageCount\n ),\n })\n);\n\n// Connector Service Account - Track which connector uses which pooled SA\nexport const connectorServiceAccount = pgTable(\n 'connector_service_account',\n {\n connectorId: text('connectorId')\n .primaryKey()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n serviceAccountId: text('serviceAccountId')\n .notNull()\n .references(() => googleServiceAccountPool.id),\n assignedAt: timestamp('assignedAt').notNull().defaultNow(),\n },\n table => ({\n saIdIdx: index('csa_service_account_id_idx').on(table.serviceAccountId),\n })\n);\n\n// NOTE: portfolio_share table has been removed (unused)\n\n// Asset Shares - Public sharing of assets\nexport const assetShare = pgTable(\n 'asset_share',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n shareToken: text('shareToken').notNull().unique(),\n accessLevel: text('accessLevel').notNull().default('view'), // 'view' | 'comment'\n expiresAt: timestamp('expiresAt'),\n accessMetadata: jsonb('accessMetadata'), // View counts, access logs, etc.\n isPublic: boolean('isPublic').notNull().default(true), // Public access toggle\n showComparisons: boolean('showComparisons').notNull().default(true), // Show 30-day comparisons\n visibleMetrics: jsonb('visibleMetrics'), // Array of visible metric keys\n ogImageType: text('ogImageType').notNull().default('valuation'), // OgImageMetricKey from shared-types\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n shareTokenIdx: index('asset_share_token_idx').on(table.shareToken),\n expiresAtIdx: index('asset_share_expires_at_idx').on(table.expiresAt),\n })\n).enableRLS();\n\n// NOTE: asset_group and asset_group_member tables have been removed (unused)\n\n// =============================================================================\n// DATA PROCESSING TABLES\n// =============================================================================\n\n// NOTE: report_metadata, analytics_request, and report_segment tables have been removed (unused)\n\n// Sync Status - Track continuous sync operations\nexport const syncStatus = pgTable(\n 'sync_status',\n {\n id: text('id').primaryKey(),\n dataConnectorId: text('dataConnectorId')\n .notNull()\n .references(() => dataConnector.id, { onDelete: 'cascade' }),\n syncType: text('syncType').notNull(), // 'full' | 'incremental' | 'manual'\n status: text('status').notNull().default('pending'), // 'pending' | 'running' | 'completed' | 'failed' | 'partial'\n startedAt: timestamp('startedAt').notNull().defaultNow(),\n completedAt: timestamp('completedAt'),\n reportsSynced: integer('reportsSynced').default(0),\n reportsTotal: integer('reportsTotal'),\n errorMessage: text('errorMessage'),\n syncMetadata: jsonb('syncMetadata'), // Detailed sync progress and results\n },\n table => ({\n connectorStatusIdx: index('sync_status_connector_status_idx').on(\n table.dataConnectorId,\n table.status\n ),\n startedAtIdx: index('sync_status_started_at_idx').on(table.startedAt),\n syncTypeIdx: index('sync_status_sync_type_idx').on(table.syncType),\n })\n).enableRLS();\n\n// Setup Progress - Track initial setup progress for users\nexport const setupProgress = pgTable(\n 'setup_progress',\n {\n id: text('id').primaryKey(),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n connectorId: text('connectorId').references(() => dataConnector.id, {\n onDelete: 'cascade',\n }),\n connectorPlatform: text('connectorPlatform')\n .notNull()\n .default('app_store_connect'),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'cascade',\n }),\n setupType: text('setupType').notNull().default('initial'), // 'initial' | 'additional' | 'linking'\n currentPhase: text('currentPhase').notNull().default('platform_select'), // 'platform_select' | 'validating' | 'discovering' | 'app_picker' | 'downloading' | 'processing' | 'calculating' | 'completed' | 'error'\n overallProgress: integer('overallProgress').notNull().default(0), // 0-100\n status: text('status').notNull().default('pending'), // 'pending' | 'in_progress' | 'completed' | 'failed'\n progressData: jsonb('progressData'), // Detailed progress information\n selectedApps: jsonb('selectedApps'), // Apps selected by user\n estimatedCompletion: timestamp('estimatedCompletion'),\n errorMessage: text('errorMessage'),\n startedAt: timestamp('startedAt').notNull().defaultNow(),\n completedAt: timestamp('completedAt'),\n lastUpdated: timestamp('lastUpdated').notNull().defaultNow(),\n },\n table => ({\n userStatusIdx: index('setup_progress_user_status_idx').on(\n table.userId,\n table.status\n ),\n orgStatusIdx: index('setup_progress_org_status_idx').on(\n table.organizationId,\n table.status\n ),\n connectorIdx: index('setup_progress_connector_idx').on(table.connectorId),\n assetIdx: index('setup_progress_asset_idx').on(table.assetId),\n currentPhaseIdx: index('setup_progress_current_phase_idx').on(\n table.currentPhase\n ),\n lastUpdatedIdx: index('setup_progress_last_updated_idx').on(\n table.lastUpdated\n ),\n })\n).enableRLS();\n\n// Exchange Rates - Historical currency exchange rates\nexport const exchangeRate = pgTable(\n 'exchange_rate',\n {\n id: text('id').primaryKey(),\n currencyCode: text('currencyCode').notNull(), // 'EUR', 'GBP', 'JPY', etc.\n dateKey: text('dateKey').notNull(), // 'YYYY-MM' format for monthly rates\n rateToUSD: decimal('rateToUSD', { precision: 15, scale: 8 }).notNull(), // Rate to convert from currency to USD (supports rates up to 9,999,999.99999999)\n source: text('source').notNull().default('freecurrencyapi'), // API source\n fetchedAt: timestamp('fetchedAt').notNull().defaultNow(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n currencyDateIdx: index('exchange_rate_currency_date_idx').on(\n table.currencyCode,\n table.dateKey\n ),\n dateKeyIdx: index('exchange_rate_date_key_idx').on(table.dateKey),\n fetchedAtIdx: index('exchange_rate_fetched_at_idx').on(table.fetchedAt),\n })\n).enableRLS();\n\n// NOTE: currency_cache table has been removed (unused)\n\n// =============================================================================\n// RELATIONSHIPS\n// =============================================================================\n\n// User Relations\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n memberships: many(member),\n invitationsSent: many(invitation),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n\n// Organization Relations\nexport const organizationRelations = relations(\n organization,\n ({ many, one }) => ({\n members: many(member),\n invitations: many(invitation),\n dataConnectors: many(dataConnector),\n assets: many(asset),\n subscription: one(subscription, {\n fields: [organization.id],\n references: [subscription.organizationId],\n }),\n orgGroupOrganizations: many(orgGroupOrganization),\n productAgentRuns: many(productAgentRun),\n usageQuotas: many(usageQuota),\n usageCreditLogs: many(usageCreditLog),\n })\n);\n\nexport const memberRelations = relations(member, ({ one }) => ({\n user: one(user, {\n fields: [member.userId],\n references: [user.id],\n }),\n organization: one(organization, {\n fields: [member.organizationId],\n references: [organization.id],\n }),\n}));\n\nexport const invitationRelations = relations(invitation, ({ one }) => ({\n organization: one(organization, {\n fields: [invitation.organizationId],\n references: [organization.id],\n }),\n inviter: one(user, {\n fields: [invitation.inviterId],\n references: [user.id],\n }),\n}));\n\n// Data Connector Relations\nexport const dataConnectorRelations = relations(\n dataConnector,\n ({ one, many }) => ({\n organization: one(organization, {\n fields: [dataConnector.organizationId],\n references: [organization.id],\n }),\n assetDataSources: many(assetDataSource),\n adCampaigns: many(adCampaign),\n syncStatuses: many(syncStatus),\n platformInvitations: many(platformInvitation),\n diagnosticRuns: many(connectorDiagnosticRun),\n serviceAccountAssignment: one(connectorServiceAccount, {\n fields: [dataConnector.id],\n references: [connectorServiceAccount.connectorId],\n }),\n })\n);\n\n// Asset Relations\nexport const assetRelations = relations(asset, ({ one, many }) => ({\n organization: one(organization, {\n fields: [asset.organizationId],\n references: [organization.id],\n }),\n dataSources: many(assetDataSource),\n adCampaigns: many(adCampaign),\n valuationHistory: many(valuationHistory),\n shares: many(assetShare),\n assetInfo: one(assetInfo, {\n fields: [asset.id],\n references: [assetInfo.assetId],\n }),\n reviewAgentSettings: one(reviewAgentSettings, {\n fields: [asset.id],\n references: [reviewAgentSettings.assetId],\n }),\n // reviews are linked by appId, not by asset relation\n reviewSyncState: one(reviewSyncState, {\n fields: [asset.id],\n references: [reviewSyncState.assetId],\n }),\n}));\n\n// Review Relations - reviews are linked by appId, not asset relation\n// No direct relation needed since we query by appId\n\n// Review Sync State Relations\nexport const reviewSyncStateRelations = relations(\n reviewSyncState,\n ({ one }) => ({\n asset: one(asset, {\n fields: [reviewSyncState.assetId],\n references: [asset.id],\n }),\n })\n);\n\n// Review Relations\nexport const reviewRelations = relations(review, ({ many }) => ({\n history: many(reviewHistory),\n}));\n\n// Review History Relations\nexport const reviewHistoryRelations = relations(reviewHistory, ({ one }) => ({\n review: one(review, {\n fields: [reviewHistory.reviewId],\n references: [review.id],\n }),\n}));\n\n// Review Agent Settings Relations\nexport const reviewAgentSettingsRelations = relations(\n reviewAgentSettings,\n ({ one }) => ({\n asset: one(asset, {\n fields: [reviewAgentSettings.assetId],\n references: [asset.id],\n }),\n })\n);\n\n// Webhook Event Relations\nexport const webhookEventRelations = relations(webhookEvent, ({ many }) => ({\n platformInvitations: many(platformInvitation),\n}));\n\n// Platform Invitation Relations\nexport const platformInvitationRelations = relations(\n platformInvitation,\n ({ one }) => ({\n dataConnector: one(dataConnector, {\n fields: [platformInvitation.dataConnectorId],\n references: [dataConnector.id],\n }),\n webhookEvent: one(webhookEvent, {\n fields: [platformInvitation.webhookEventId],\n references: [webhookEvent.id],\n }),\n })\n);\n\n// Connector Diagnostic Run Relations\nexport const connectorDiagnosticRunRelations = relations(\n connectorDiagnosticRun,\n ({ one }) => ({\n connector: one(dataConnector, {\n fields: [connectorDiagnosticRun.connectorId],\n references: [dataConnector.id],\n }),\n organization: one(organization, {\n fields: [connectorDiagnosticRun.organizationId],\n references: [organization.id],\n }),\n user: one(user, {\n fields: [connectorDiagnosticRun.triggeredBy],\n references: [user.id],\n }),\n })\n);\n\n// Google Service Account Pool Relations\nexport const googleServiceAccountPoolRelations = relations(\n googleServiceAccountPool,\n ({ many }) => ({\n connectorAssignments: many(connectorServiceAccount),\n })\n);\n\n// Connector Service Account Relations\nexport const connectorServiceAccountRelations = relations(\n connectorServiceAccount,\n ({ one }) => ({\n connector: one(dataConnector, {\n fields: [connectorServiceAccount.connectorId],\n references: [dataConnector.id],\n }),\n serviceAccount: one(googleServiceAccountPool, {\n fields: [connectorServiceAccount.serviceAccountId],\n references: [googleServiceAccountPool.id],\n }),\n })\n);\n\nexport const assetDataSourceRelations = relations(\n assetDataSource,\n ({ one }) => ({\n asset: one(asset, {\n fields: [assetDataSource.assetId],\n references: [asset.id],\n }),\n dataConnector: one(dataConnector, {\n fields: [assetDataSource.dataConnectorId],\n references: [dataConnector.id],\n }),\n })\n);\n\nexport const adCampaignRelations = relations(adCampaign, ({ one, many }) => ({\n dataConnector: one(dataConnector, {\n fields: [adCampaign.dataConnectorId],\n references: [dataConnector.id],\n }),\n asset: one(asset, {\n fields: [adCampaign.assetId],\n references: [asset.id],\n }),\n keywords: many(adKeyword),\n searchTerms: many(adSearchTerm),\n}));\n\nexport const adKeywordRelations = relations(adKeyword, ({ one, many }) => ({\n campaign: one(adCampaign, {\n fields: [adKeyword.adCampaignId],\n references: [adCampaign.id],\n }),\n metrics: many(adKeywordMetric),\n}));\n\nexport const adKeywordMetricRelations = relations(adKeywordMetric, ({ one }) => ({\n keyword: one(adKeyword, {\n fields: [adKeywordMetric.adKeywordId],\n references: [adKeyword.id],\n }),\n}));\n\nexport const adSearchTermRelations = relations(adSearchTerm, ({ one }) => ({\n campaign: one(adCampaign, {\n fields: [adSearchTerm.adCampaignId],\n references: [adCampaign.id],\n }),\n}));\n\nexport const valuationHistoryRelations = relations(\n valuationHistory,\n ({ one }) => ({\n asset: one(asset, {\n fields: [valuationHistory.assetId],\n references: [asset.id],\n }),\n // assetMetric relation removed - now uses TimescaleDB\n })\n);\n\nexport const assetShareRelations = relations(assetShare, ({ one }) => ({\n asset: one(asset, {\n fields: [assetShare.assetId],\n references: [asset.id],\n }),\n}));\n\nexport const assetInfoRelations = relations(assetInfo, ({ one }) => ({\n asset: one(asset, {\n fields: [assetInfo.assetId],\n references: [asset.id],\n }),\n}));\n\n// Sync Status Relations\nexport const syncStatusRelations = relations(syncStatus, ({ one }) => ({\n dataConnector: one(dataConnector, {\n fields: [syncStatus.dataConnectorId],\n references: [dataConnector.id],\n }),\n}));\n\nexport const setupProgressRelations = relations(setupProgress, ({ one }) => ({\n user: one(user, {\n fields: [setupProgress.userId],\n references: [user.id],\n }),\n organization: one(organization, {\n fields: [setupProgress.organizationId],\n references: [organization.id],\n }),\n dataConnector: one(dataConnector, {\n fields: [setupProgress.connectorId],\n references: [dataConnector.id],\n }),\n asset: one(asset, {\n fields: [setupProgress.assetId],\n references: [asset.id],\n }),\n}));\n\n// =============================================================================\n// EMAIL NOTIFICATION TABLES\n// =============================================================================\n\n// Email Deliveries - Track all email notifications sent\nexport const emailDelivery = pgTable(\n 'email_delivery',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n emailType: text('emailType').notNull(), // 'weekly_report' | 'monthly_summary' | 'valuation_complete' etc.\n recipientEmail: text('recipientEmail').notNull(),\n reportPeriodStart: date('reportPeriodStart'), // For time-based reports\n reportPeriodEnd: date('reportPeriodEnd'),\n status: text('status').notNull().default('pending'), // 'pending' | 'sent' | 'failed' | 'skipped'\n emailData: jsonb('emailData'), // The actual data sent in the email (metrics, etc.)\n errorMessage: text('errorMessage'),\n sentAt: timestamp('sentAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgTypeIdx: index('email_delivery_org_type_idx').on(\n table.organizationId,\n table.emailType\n ),\n userTypeIdx: index('email_delivery_user_type_idx').on(\n table.userId,\n table.emailType\n ),\n periodIdx: index('email_delivery_period_idx').on(\n table.reportPeriodStart,\n table.reportPeriodEnd\n ),\n statusIdx: index('email_delivery_status_idx').on(table.status),\n sentAtIdx: index('email_delivery_sent_at_idx').on(table.sentAt),\n // Unique constraint to prevent duplicate sends for same period\n uniqueDelivery: unique('email_delivery_unique').on(\n table.organizationId,\n table.userId,\n table.emailType,\n table.reportPeriodStart,\n table.reportPeriodEnd\n ),\n })\n).enableRLS();\n\nexport type EmailDeliveryType = typeof emailDelivery.$inferInsert;\n\n// Email Notification Preferences - User preferences for email notifications\nexport const emailNotificationPreference = pgTable(\n 'email_notification_preference',\n {\n id: text('id').primaryKey(),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n emailType: text('emailType').notNull(), // 'weekly_report' | 'monthly_summary' etc.\n enabled: boolean('enabled').notNull().default(true),\n frequency: text('frequency'), // 'weekly' | 'monthly' for flexible scheduling\n preferredDay: integer('preferredDay'), // Day of week (0-6) or day of month (1-31)\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n userOrgIdx: index('email_pref_user_org_idx').on(\n table.userId,\n table.organizationId\n ),\n typeEnabledIdx: index('email_pref_type_enabled_idx').on(\n table.emailType,\n table.enabled\n ),\n // Unique constraint: one preference per user per org per email type\n uniquePref: unique('email_pref_unique').on(\n table.userId,\n table.organizationId,\n table.emailType\n ),\n })\n).enableRLS();\n\nexport type EmailNotificationPreferenceType =\n typeof emailNotificationPreference.$inferInsert;\n\n// =============================================================================\n// AI ADVICE TABLES\n// =============================================================================\n\nexport const aiAdvice = pgTable(\n 'ai_advice',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n year: integer('year'),\n month: integer('month'),\n model: text('model').notNull(),\n promptVersion: text('promptVersion'),\n requestPayload: jsonb('requestPayload').notNull(),\n advice: jsonb('advice').notNull(),\n metadata: jsonb('metadata'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n assetCreatedIdx: index('ai_advice_asset_created_idx').on(\n table.assetId,\n table.createdAt\n ),\n assetPeriodIdx: index('ai_advice_asset_period_idx').on(\n table.assetId,\n table.year,\n table.month\n ),\n organizationIdIdx: index('ai_advice_organization_id_idx').on(\n table.organizationId\n ),\n })\n).enableRLS();\n\nexport type AiAdviceType = typeof aiAdvice.$inferInsert;\n\n// =============================================================================\n// CHAT SYSTEM TABLES\n// =============================================================================\n\n// Chat Conversations - AI assistant conversations\nexport const chatConversation = pgTable(\n 'chat_conversation',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n title: text('title').notNull(),\n visibility: text('visibility', { enum: ['private', 'organization'] })\n .notNull()\n .default('private'),\n lastContext: jsonb('lastContext'), // AI usage tracking and context\n activeStreamId: text('activeStreamId'), // Active resumable stream ID for resume functionality\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n userOrgIdx: index('chat_conversation_user_org_idx').on(\n table.userId,\n table.organizationId\n ),\n orgVisibilityIdx: index('chat_conversation_org_visibility_idx').on(\n table.organizationId,\n table.visibility\n ),\n createdAtIdx: index('chat_conversation_created_at_idx').on(table.createdAt),\n updatedAtIdx: index('chat_conversation_updated_at_idx').on(table.updatedAt),\n })\n).enableRLS();\n\nexport type ChatConversationType = typeof chatConversation.$inferInsert;\n\n// Chat Messages - Individual messages in conversations\nexport const chatMessage = pgTable(\n 'chat_message',\n {\n id: text('id').primaryKey(),\n conversationId: text('conversationId')\n .notNull()\n .references(() => chatConversation.id, { onDelete: 'cascade' }),\n role: text('role', { enum: ['user', 'assistant'] }).notNull(),\n parts: jsonb('parts').notNull(), // Message content parts (text, files, tool calls)\n attachments: jsonb('attachments').notNull().default('[]'), // File attachments\n metadata: jsonb('metadata'), // Reasoning, tool results, usage stats\n createdAt: timestamp('createdAt').notNull(),\n },\n table => ({\n conversationIdx: index('chat_message_conversation_idx').on(\n table.conversationId\n ),\n createdAtIdx: index('chat_message_created_at_idx').on(table.createdAt),\n roleIdx: index('chat_message_role_idx').on(table.role),\n })\n).enableRLS();\n\nexport type ChatMessageType = typeof chatMessage.$inferInsert;\n\n// Chat Artifacts - Generated charts, analysis, reports\nexport const chatArtifact = pgTable(\n 'chat_artifact',\n {\n id: text('id').notNull(),\n conversationId: text('conversationId')\n .notNull()\n .references(() => chatConversation.id, { onDelete: 'cascade' }),\n kind: text('kind', {\n enum: ['chart', 'sheet', 'analysis', 'report'],\n }).notNull(),\n title: text('title').notNull(),\n content: jsonb('content').notNull(), // Chart data, analysis content\n config: jsonb('config'), // Chart configuration, styling options\n version: integer('version').notNull().default(1),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n // Composite primary key for versioning support\n pk: primaryKey({ columns: [table.id, table.version] }),\n conversationIdx: index('chat_artifact_conversation_idx').on(\n table.conversationId\n ),\n kindIdx: index('chat_artifact_kind_idx').on(table.kind),\n createdAtIdx: index('chat_artifact_created_at_idx').on(table.createdAt),\n })\n).enableRLS();\n\nexport type ChatArtifactType = typeof chatArtifact.$inferInsert;\n\n// Chat Message Votes - User feedback on AI responses\nexport const chatVote = pgTable(\n 'chat_vote',\n {\n conversationId: text('conversationId')\n .notNull()\n .references(() => chatConversation.id, { onDelete: 'cascade' }),\n messageId: text('messageId')\n .notNull()\n .references(() => chatMessage.id, { onDelete: 'cascade' }),\n isUpvoted: boolean('isUpvoted').notNull(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n pk: index('chat_vote_pk').on(table.conversationId, table.messageId),\n conversationIdx: index('chat_vote_conversation_idx').on(\n table.conversationId\n ),\n })\n).enableRLS();\n\nexport type ChatVoteType = typeof chatVote.$inferInsert;\n\n// Chat Streams - For resumable streaming support\nexport const chatStream = pgTable(\n 'chat_stream',\n {\n id: text('id').primaryKey(),\n conversationId: text('conversationId')\n .notNull()\n .references(() => chatConversation.id, { onDelete: 'cascade' }),\n chunks: jsonb('chunks').notNull().default('[]'), // Store SSE chunks for replay\n isComplete: boolean('isComplete').notNull().default(false),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n conversationIdx: index('chat_stream_conversation_idx').on(\n table.conversationId\n ),\n createdAtIdx: index('chat_stream_created_at_idx').on(table.createdAt),\n })\n).enableRLS();\n\nexport type ChatStreamType = typeof chatStream.$inferInsert;\n\n// =============================================================================\n// CHAT RELATIONS\n// =============================================================================\n\nexport const chatConversationRelations = relations(\n chatConversation,\n ({ one, many }) => ({\n user: one(user, {\n fields: [chatConversation.userId],\n references: [user.id],\n }),\n organization: one(organization, {\n fields: [chatConversation.organizationId],\n references: [organization.id],\n }),\n messages: many(chatMessage),\n artifacts: many(chatArtifact),\n votes: many(chatVote),\n streams: many(chatStream),\n })\n);\n\nexport const chatMessageRelations = relations(chatMessage, ({ one }) => ({\n conversation: one(chatConversation, {\n fields: [chatMessage.conversationId],\n references: [chatConversation.id],\n }),\n}));\n\nexport const chatArtifactRelations = relations(chatArtifact, ({ one }) => ({\n conversation: one(chatConversation, {\n fields: [chatArtifact.conversationId],\n references: [chatConversation.id],\n }),\n}));\n\nexport const chatVoteRelations = relations(chatVote, ({ one }) => ({\n conversation: one(chatConversation, {\n fields: [chatVote.conversationId],\n references: [chatConversation.id],\n }),\n message: one(chatMessage, {\n fields: [chatVote.messageId],\n references: [chatMessage.id],\n }),\n}));\n\nexport const chatStreamRelations = relations(chatStream, ({ one }) => ({\n conversation: one(chatConversation, {\n fields: [chatStream.conversationId],\n references: [chatConversation.id],\n }),\n}));\n\n// =============================================================================\n// EMAIL NOTIFICATION RELATIONS\n// =============================================================================\n\nexport const emailDeliveryRelations = relations(emailDelivery, ({ one }) => ({\n organization: one(organization, {\n fields: [emailDelivery.organizationId],\n references: [organization.id],\n }),\n user: one(user, {\n fields: [emailDelivery.userId],\n references: [user.id],\n }),\n}));\n\nexport const emailNotificationPreferenceRelations = relations(\n emailNotificationPreference,\n ({ one }) => ({\n user: one(user, {\n fields: [emailNotificationPreference.userId],\n references: [user.id],\n }),\n organization: one(organization, {\n fields: [emailNotificationPreference.organizationId],\n references: [organization.id],\n }),\n })\n);\n\n// =============================================================================\n// SUBSCRIPTION RELATIONS\n// =============================================================================\n\nexport const subscriptionRelations = relations(subscription, ({ one }) => ({\n organization: one(organization, {\n fields: [subscription.organizationId],\n references: [organization.id],\n }),\n}));\n\n// =============================================================================\n// ANOMALY DETECTION TABLES\n// =============================================================================\n\n// Detected anomalies - stores anomalies found in revenue/downloads data\nexport const anomaly = pgTable(\n 'anomaly',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n\n // When & What\n detectedAt: timestamp('detected_at').notNull().defaultNow(),\n anomalyDate: date('anomaly_date').notNull(),\n metricName: text('metric_name').notNull(), // 'proceeds' | 'units'\n sourceType: text('source_type'), // 'app_store_connect' | 'google_play' | null (aggregated)\n\n // Type & Severity\n type: text('type').notNull(), // 'surge' | 'decline'\n severity: text('severity').notNull(), // 'low' | 'medium' | 'high' | 'critical'\n\n // Values\n actualValue: decimal('actual_value', { precision: 20, scale: 4 }).notNull(),\n expectedValue: decimal('expected_value', {\n precision: 20,\n scale: 4,\n }).notNull(),\n expectedLower: decimal('expected_lower', {\n precision: 20,\n scale: 4,\n }).notNull(),\n expectedUpper: decimal('expected_upper', {\n precision: 20,\n scale: 4,\n }).notNull(),\n deviationPercent: decimal('deviation_percent', {\n precision: 10,\n scale: 4,\n }).notNull(),\n\n // Decomposition components\n trendComponent: decimal('trend_component', { precision: 20, scale: 4 }),\n seasonalComponent: decimal('seasonal_component', {\n precision: 20,\n scale: 4,\n }),\n residualComponent: decimal('residual_component', {\n precision: 20,\n scale: 4,\n }),\n\n // Multi-scale comparisons (JSONB for flexibility)\n comparisons: jsonb('comparisons').notNull(),\n\n // Confidence & Metadata\n confidence: decimal('confidence', { precision: 5, scale: 4 }).notNull(), // 0.0000 to 1.0000\n explanation: text('explanation'),\n suggestedActions: jsonb('suggested_actions'),\n\n // User interaction\n status: text('status').notNull().default('new'), // 'new' | 'viewed' | 'acknowledged' | 'dismissed'\n viewedAt: timestamp('viewed_at'),\n acknowledgedAt: timestamp('acknowledged_at'),\n dismissedAt: timestamp('dismissed_at'),\n dismissedReason: text('dismissed_reason'),\n\n // Timestamps\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n assetDateIdx: index('anomaly_asset_date_idx').on(\n table.assetId,\n table.anomalyDate\n ),\n orgStatusIdx: index('anomaly_org_status_idx').on(\n table.organizationId,\n table.status\n ),\n severityIdx: index('anomaly_severity_idx').on(\n table.severity,\n table.detectedAt\n ),\n metricIdx: index('anomaly_metric_idx').on(table.metricName),\n sourceTypeIdx: index('anomaly_source_type_idx').on(table.sourceType),\n // Unique constraint to prevent duplicate anomalies for same date/metric/source\n uniqueAnomalyPerDateMetric: unique('anomaly_asset_date_metric_source_unique').on(\n table.assetId,\n table.anomalyDate,\n table.metricName,\n table.sourceType\n ),\n })\n).enableRLS();\n\nexport type AnomalyType = typeof anomaly.$inferInsert;\nexport type AnomalySelect = typeof anomaly.$inferSelect;\n\n// NOTE: metric_baseline table has been removed (unused)\n\n// =============================================================================\n// REVIEW ANALYSIS\n// =============================================================================\n\nexport const reviewAnalysis = pgTable(\n 'review_analysis',\n {\n id: text('id').primaryKey(),\n assetId: text('asset_id')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n\n // Analysis results (stored as JSON)\n pros: jsonb('pros')\n .notNull()\n .$type<Array<{ point: string; frequency: number; examples: string[] }>>(),\n cons: jsonb('cons')\n .notNull()\n .$type<Array<{ point: string; frequency: number; examples: string[] }>>(),\n overallSentiment: text('overall_sentiment').notNull(), // 'positive' | 'neutral' | 'negative'\n totalReviewsAnalyzed: integer('total_reviews_analyzed').notNull(),\n dateRangeStart: text('date_range_start'),\n dateRangeEnd: text('date_range_end'),\n\n // Filters used for this analysis (stored as JSON)\n filters: jsonb('filters').$type<{\n storeFronts?: string[];\n appVersions?: string[];\n startDate?: string;\n endDate?: string;\n }>(),\n\n createdAt: timestamp('created_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n table => ({\n assetIdx: index('review_analysis_asset_idx').on(table.assetId),\n orgIdx: index('review_analysis_org_idx').on(table.organizationId),\n createdAtIdx: index('review_analysis_created_at_idx').on(table.createdAt),\n })\n).enableRLS();\n\nexport type ReviewAnalysisType = typeof reviewAnalysis.$inferInsert;\nexport type ReviewAnalysisSelect = typeof reviewAnalysis.$inferSelect;\n\nexport const reviewAnalysisRelations = relations(reviewAnalysis, ({ one }) => ({\n asset: one(asset, {\n fields: [reviewAnalysis.assetId],\n references: [asset.id],\n }),\n organization: one(organization, {\n fields: [reviewAnalysis.organizationId],\n references: [organization.id],\n }),\n}));\n\n// =============================================================================\n// ANOMALY RELATIONS\n// =============================================================================\n\nexport const anomalyRelations = relations(anomaly, ({ one }) => ({\n asset: one(asset, {\n fields: [anomaly.assetId],\n references: [asset.id],\n }),\n organization: one(organization, {\n fields: [anomaly.organizationId],\n references: [organization.id],\n }),\n}));\n\n// NOTE: metric_baseline table has been removed (unused)\n\n// Onboarding Step Preferences - Track which onboarding steps users have skipped\nexport const onboardingStepPreference = pgTable(\n 'onboarding_step_preference',\n {\n id: text('id').primaryKey(),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n stepId: text('stepId').notNull(),\n isSkipped: boolean('isSkipped').notNull().default(false),\n skippedAt: timestamp('skippedAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n userOrgIdx: index('onboarding_pref_user_org_idx').on(\n table.userId,\n table.organizationId\n ),\n uniquePref: unique('onboarding_pref_unique').on(\n table.userId,\n table.organizationId,\n table.stepId\n ),\n })\n).enableRLS();\n\nexport type OnboardingStepPreferenceType =\n typeof onboardingStepPreference.$inferInsert\n\n// =============================================================================\n// SLACK INTEGRATION TABLES\n// =============================================================================\n\n// Slack Integration - Stores the Slack workspace connection (one per org)\nexport const slackIntegration = pgTable(\n 'slack_integration',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .unique()\n .references(() => organization.id, { onDelete: 'cascade' }),\n slackTeamId: text('slack_team_id').notNull().unique(), // Slack workspace ID\n slackTeamName: text('slack_team_name').notNull(), // Display name\n botToken: text('bot_token').notNull(), // OAuth bot token (encrypted at app level)\n botUserId: text('bot_user_id').notNull(), // Bot's Slack user ID (to filter own messages)\n installedBy: text('installed_by')\n .notNull()\n .references(() => user.id, { onDelete: 'set null' }),\n installedAt: timestamp('installed_at').notNull().defaultNow(),\n scopes: text('scopes')\n .array()\n .notNull()\n .default(sql`'{}'::text[]`), // Granted OAuth scopes\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('slack_integration_org_idx').on(table.organizationId),\n teamIdx: index('slack_integration_team_idx').on(table.slackTeamId),\n })\n).enableRLS();\n\nexport type SlackIntegrationType = typeof slackIntegration.$inferInsert;\nexport type SlackIntegrationSelect = typeof slackIntegration.$inferSelect;\n\n// Slack Notification Subscription - Which channels receive which notifications\nexport const slackNotificationSubscription = pgTable(\n 'slack_notification_subscription',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n slackChannelId: text('slack_channel_id').notNull(), // Target channel\n slackChannelName: text('slack_channel_name').notNull(), // For display\n eventType: text('event_type', {\n enum: ['review', 'anomaly', 'digest_daily', 'digest_weekly', 'milestone'],\n }).notNull(),\n assetId: text('asset_id').references(() => asset.id, {\n onDelete: 'cascade',\n }), // Specific app, or null for all apps\n createdBy: text('created_by')\n .notNull()\n .references(() => user.id, { onDelete: 'set null' }),\n enabled: boolean('enabled').notNull().default(true),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('slack_notification_sub_org_idx').on(table.organizationId),\n channelIdx: index('slack_notification_sub_channel_idx').on(\n table.slackChannelId\n ),\n eventTypeIdx: index('slack_notification_sub_event_type_idx').on(\n table.eventType\n ),\n assetIdx: index('slack_notification_sub_asset_idx').on(table.assetId),\n // Unique constraint: one subscription per org/channel/event/asset combo\n uniqueSub: unique('slack_notification_sub_unique').on(\n table.organizationId,\n table.slackChannelId,\n table.eventType,\n table.assetId\n ),\n })\n).enableRLS();\n\nexport type SlackNotificationSubscriptionType =\n typeof slackNotificationSubscription.$inferInsert;\nexport type SlackNotificationSubscriptionSelect =\n typeof slackNotificationSubscription.$inferSelect;\n\n// Slack Conversation - Links Slack threads to Fload chat context\nexport const slackConversation = pgTable(\n 'slack_conversation',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n slackChannelId: text('slack_channel_id').notNull(),\n slackThreadTs: text('slack_thread_ts').notNull(), // Thread timestamp (Slack's thread ID)\n chatConversationId: text('chat_conversation_id').references(\n () => chatConversation.id,\n { onDelete: 'set null' }\n ), // Link to Fload conversation\n createdAt: timestamp('created_at').notNull().defaultNow(),\n lastActivityAt: timestamp('last_activity_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('slack_conversation_org_idx').on(table.organizationId),\n threadIdx: index('slack_conversation_thread_idx').on(\n table.slackChannelId,\n table.slackThreadTs\n ),\n chatConvIdx: index('slack_conversation_chat_conv_idx').on(\n table.chatConversationId\n ),\n // Unique constraint: one conversation per channel/thread combo\n uniqueThread: unique('slack_conversation_thread_unique').on(\n table.slackChannelId,\n table.slackThreadTs\n ),\n })\n).enableRLS();\n\nexport type SlackConversationType = typeof slackConversation.$inferInsert;\nexport type SlackConversationSelect = typeof slackConversation.$inferSelect;\n\n// =============================================================================\n// SLACK RELATIONS\n// =============================================================================\n\nexport const slackIntegrationRelations = relations(\n slackIntegration,\n ({ one }) => ({\n organization: one(organization, {\n fields: [slackIntegration.organizationId],\n references: [organization.id],\n }),\n installedByUser: one(user, {\n fields: [slackIntegration.installedBy],\n references: [user.id],\n }),\n })\n);\n\nexport const slackNotificationSubscriptionRelations = relations(\n slackNotificationSubscription,\n ({ one }) => ({\n organization: one(organization, {\n fields: [slackNotificationSubscription.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [slackNotificationSubscription.assetId],\n references: [asset.id],\n }),\n createdByUser: one(user, {\n fields: [slackNotificationSubscription.createdBy],\n references: [user.id],\n }),\n })\n);\n\nexport const slackConversationRelations = relations(\n slackConversation,\n ({ one }) => ({\n organization: one(organization, {\n fields: [slackConversation.organizationId],\n references: [organization.id],\n }),\n chatConversation: one(chatConversation, {\n fields: [slackConversation.chatConversationId],\n references: [chatConversation.id],\n }),\n })\n);\n\n// =============================================================================\n// DISCORD INTEGRATION TABLES\n// =============================================================================\n\n// Discord Integration - Stores the Discord guild (server) connection (one per org)\nexport const discordIntegration = pgTable(\n 'discord_integration',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .unique()\n .references(() => organization.id, { onDelete: 'cascade' }),\n discordGuildId: text('discord_guild_id').notNull().unique(), // Discord server ID\n discordGuildName: text('discord_guild_name').notNull(), // Display name\n botToken: text('bot_token').notNull(), // Bot token (encrypted at app level)\n applicationId: text('application_id').notNull(), // Discord application ID\n botUserId: text('bot_user_id').notNull(), // Bot's Discord user ID (to filter own messages)\n installedBy: text('installed_by')\n .notNull()\n .references(() => user.id, { onDelete: 'set null' }),\n installedAt: timestamp('installed_at').notNull().defaultNow(),\n scopes: text('scopes')\n .array()\n .notNull()\n .default(sql`'{}'::text[]`), // Granted OAuth scopes\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('discord_integration_org_idx').on(table.organizationId),\n guildIdx: index('discord_integration_guild_idx').on(table.discordGuildId),\n })\n).enableRLS();\n\nexport type DiscordIntegrationType = typeof discordIntegration.$inferInsert;\nexport type DiscordIntegrationSelect = typeof discordIntegration.$inferSelect;\n\n// Discord Notification Subscription - Which channels receive which notifications\nexport const discordNotificationSubscription = pgTable(\n 'discord_notification_subscription',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n discordChannelId: text('discord_channel_id').notNull(), // Target channel\n discordChannelName: text('discord_channel_name').notNull(), // For display\n eventType: text('event_type', {\n enum: ['review', 'anomaly', 'digest_daily', 'digest_weekly', 'milestone'],\n }).notNull(),\n assetId: text('asset_id').references(() => asset.id, {\n onDelete: 'cascade',\n }), // Specific app, or null for all apps\n createdBy: text('created_by')\n .notNull()\n .references(() => user.id, { onDelete: 'set null' }),\n enabled: boolean('enabled').notNull().default(true),\n createdAt: timestamp('created_at').notNull().defaultNow(),\n updatedAt: timestamp('updated_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('discord_notification_sub_org_idx').on(table.organizationId),\n channelIdx: index('discord_notification_sub_channel_idx').on(\n table.discordChannelId\n ),\n eventTypeIdx: index('discord_notification_sub_event_type_idx').on(\n table.eventType\n ),\n assetIdx: index('discord_notification_sub_asset_idx').on(table.assetId),\n // Unique constraint: one subscription per org/channel/event/asset combo\n uniqueSub: unique('discord_notification_sub_unique').on(\n table.organizationId,\n table.discordChannelId,\n table.eventType,\n table.assetId\n ),\n })\n).enableRLS();\n\nexport type DiscordNotificationSubscriptionType =\n typeof discordNotificationSubscription.$inferInsert;\nexport type DiscordNotificationSubscriptionSelect =\n typeof discordNotificationSubscription.$inferSelect;\n\n// Discord Conversation - Links Discord threads to Fload chat context\nexport const discordConversation = pgTable(\n 'discord_conversation',\n {\n id: text('id').primaryKey(),\n organizationId: text('organization_id')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n discordChannelId: text('discord_channel_id').notNull(),\n discordThreadId: text('discord_thread_id').notNull(), // Thread ID (or message ID for non-thread context)\n chatConversationId: text('chat_conversation_id').references(\n () => chatConversation.id,\n { onDelete: 'set null' }\n ), // Link to Fload conversation\n createdAt: timestamp('created_at').notNull().defaultNow(),\n lastActivityAt: timestamp('last_activity_at').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('discord_conversation_org_idx').on(table.organizationId),\n threadIdx: index('discord_conversation_thread_idx').on(\n table.discordChannelId,\n table.discordThreadId\n ),\n chatConvIdx: index('discord_conversation_chat_conv_idx').on(\n table.chatConversationId\n ),\n // Unique constraint: one conversation per channel/thread combo\n uniqueThread: unique('discord_conversation_thread_unique').on(\n table.discordChannelId,\n table.discordThreadId\n ),\n })\n).enableRLS();\n\nexport type DiscordConversationType = typeof discordConversation.$inferInsert;\nexport type DiscordConversationSelect = typeof discordConversation.$inferSelect;\n\n// =============================================================================\n// DISCORD RELATIONS\n// =============================================================================\n\nexport const discordIntegrationRelations = relations(\n discordIntegration,\n ({ one }) => ({\n organization: one(organization, {\n fields: [discordIntegration.organizationId],\n references: [organization.id],\n }),\n installedByUser: one(user, {\n fields: [discordIntegration.installedBy],\n references: [user.id],\n }),\n })\n);\n\nexport const discordNotificationSubscriptionRelations = relations(\n discordNotificationSubscription,\n ({ one }) => ({\n organization: one(organization, {\n fields: [discordNotificationSubscription.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [discordNotificationSubscription.assetId],\n references: [asset.id],\n }),\n createdByUser: one(user, {\n fields: [discordNotificationSubscription.createdBy],\n references: [user.id],\n }),\n })\n);\n\nexport const discordConversationRelations = relations(\n discordConversation,\n ({ one }) => ({\n organization: one(organization, {\n fields: [discordConversation.organizationId],\n references: [organization.id],\n }),\n chatConversation: one(chatConversation, {\n fields: [discordConversation.chatConversationId],\n references: [chatConversation.id],\n }),\n })\n);\n\n// =============================================================================\n// FEATURE FLAGS\n// =============================================================================\n\n// Feature - defines available features that can be gated\nexport const feature = pgTable('feature', {\n id: text('id').primaryKey(),\n name: text('name').notNull().unique(), // e.g., \"meta-ads\"\n description: text('description'),\n enabled: boolean('enabled').notNull().default(true), // global kill switch\n enabledForAll: boolean('enabledForAll').notNull().default(false), // bypass org_group check \u2014 release to all orgs\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\n// Organization Group - groups of organizations for feature access\nexport const orgGroup = pgTable('org_group', {\n id: text('id').primaryKey(),\n name: text('name').notNull().unique(), // e.g., \"beta-orgs\"\n description: text('description'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n}).enableRLS();\n\n// Feature-OrgGroup junction - which groups have access to which features\nexport const featureOrgGroup = pgTable(\n 'feature_org_group',\n {\n id: text('id').primaryKey(),\n featureId: text('featureId')\n .notNull()\n .references(() => feature.id, { onDelete: 'cascade' }),\n orgGroupId: text('orgGroupId')\n .notNull()\n .references(() => orgGroup.id, { onDelete: 'cascade' }),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n uniqueFeatureGroup: unique('feature_org_group_unique').on(\n table.featureId,\n table.orgGroupId\n ),\n featureIdx: index('feature_org_group_feature_idx').on(table.featureId),\n groupIdx: index('feature_org_group_group_idx').on(table.orgGroupId),\n })\n).enableRLS();\n\n// OrgGroup-Organization junction - which organizations belong to which groups\nexport const orgGroupOrganization = pgTable(\n 'org_group_organization',\n {\n id: text('id').primaryKey(),\n orgGroupId: text('orgGroupId')\n .notNull()\n .references(() => orgGroup.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n uniqueGroupOrg: unique('org_group_organization_unique').on(\n table.orgGroupId,\n table.organizationId\n ),\n groupIdx: index('org_group_organization_group_idx').on(table.orgGroupId),\n orgIdx: index('org_group_organization_org_idx').on(table.organizationId),\n })\n).enableRLS();\n\n// Feature Flag Relations\nexport const featureRelations = relations(feature, ({ many }) => ({\n featureOrgGroups: many(featureOrgGroup),\n}));\n\nexport const orgGroupRelations = relations(orgGroup, ({ many }) => ({\n featureOrgGroups: many(featureOrgGroup),\n orgGroupOrganizations: many(orgGroupOrganization),\n}));\n\nexport const featureOrgGroupRelations = relations(\n featureOrgGroup,\n ({ one }) => ({\n feature: one(feature, {\n fields: [featureOrgGroup.featureId],\n references: [feature.id],\n }),\n orgGroup: one(orgGroup, {\n fields: [featureOrgGroup.orgGroupId],\n references: [orgGroup.id],\n }),\n })\n);\n\nexport const orgGroupOrganizationRelations = relations(\n orgGroupOrganization,\n ({ one }) => ({\n orgGroup: one(orgGroup, {\n fields: [orgGroupOrganization.orgGroupId],\n references: [orgGroup.id],\n }),\n organization: one(organization, {\n fields: [orgGroupOrganization.organizationId],\n references: [organization.id],\n }),\n })\n);\n\n// =============================================================================\n// PRODUCT AGENT\n// =============================================================================\n\nexport const productAgentRun = pgTable(\n 'product_agent_run',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'set null',\n }),\n appStoreUrl: text('appStoreUrl').notNull(),\n appName: text('appName'),\n appIconUrl: text('appIconUrl'),\n platform: text('platform').notNull().default('ios'),\n jobId: text('jobId'),\n status: text('status').notNull().default('pending'), // pending | running | completed | failed\n report: jsonb('report'), // Full OnboardingReport as JSONB\n screenshots: jsonb('screenshots').default([]), // Base64 strings array\n sessionId: text('sessionId'),\n errorMessage: text('errorMessage'),\n triggeredBy: text('triggeredBy').notNull().default('manual'), // onboarding | manual\n isFreeRun: boolean('isFreeRun').notNull().default(false),\n startedAt: timestamp('startedAt'),\n completedAt: timestamp('completedAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('product_agent_run_org_idx').on(table.organizationId),\n assetIdx: index('product_agent_run_asset_idx').on(table.assetId),\n orgStatusIdx: index('product_agent_run_org_status_idx').on(\n table.organizationId,\n table.status\n ),\n })\n).enableRLS();\n\nexport const productAgentRunRelations = relations(\n productAgentRun,\n ({ one }) => ({\n organization: one(organization, {\n fields: [productAgentRun.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [productAgentRun.assetId],\n references: [asset.id],\n }),\n })\n);\n\n// =============================================================================\n// USAGE QUOTA\n// =============================================================================\n\nexport const usageQuota = pgTable(\n 'usage_quota',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n feature: text('feature').notNull(), // 'product_agent' | 'review_reply' | 'chat_message'\n used: integer('used').notNull().default(0),\n periodStart: timestamp('periodStart').notNull(),\n periodEnd: timestamp('periodEnd').notNull(),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgFeaturePeriodIdx: uniqueIndex('usage_quota_org_feature_period_idx').on(\n table.organizationId,\n table.feature,\n table.periodStart\n ),\n })\n).enableRLS();\n\nexport const usageQuotaRelations = relations(usageQuota, ({ one }) => ({\n organization: one(organization, {\n fields: [usageQuota.organizationId],\n references: [organization.id],\n }),\n}));\n\n// =============================================================================\n// USAGE CREDIT LOG\n// =============================================================================\n\nexport const usageCreditLog = pgTable(\n 'usage_credit_log',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n amount: integer('amount').notNull(),\n source: text('source').notNull(), // e.g. 'agent:review', 'chat:web', 'chat:slack', 'review:translate'\n metadata: jsonb('metadata'), // optional context (agentRunId, assetId, etc.)\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('usage_credit_log_org_idx').on(table.organizationId),\n orgCreatedIdx: index('usage_credit_log_org_created_idx').on(\n table.organizationId,\n table.createdAt\n ),\n })\n).enableRLS();\n\nexport const usageCreditLogRelations = relations(usageCreditLog, ({ one }) => ({\n organization: one(organization, {\n fields: [usageCreditLog.organizationId],\n references: [organization.id],\n }),\n}));\n\n// =============================================================================\n// ASO AGENT (PHASE 1)\n// =============================================================================\n\nexport const asoAgentSettings = pgTable(\n 'aso_agent_settings',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n mode: text('mode', {\n enum: ['monitor', 'draft', 'auto'],\n })\n .notNull()\n .default('monitor'),\n locales: text('locales')\n .array()\n .notNull()\n .default(sql`'{}'::text[]`),\n guardrails: jsonb('guardrails').notNull().default(sql`'{}'::jsonb`),\n notifications: jsonb('notifications').notNull().default(sql`'{}'::jsonb`),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgAssetIdx: index('aso_agent_settings_org_asset_idx').on(\n table.organizationId,\n table.assetId\n ),\n modeIdx: index('aso_agent_settings_mode_idx').on(table.mode),\n })\n).enableRLS();\n\nexport const asoRecommendation = pgTable(\n 'aso_recommendation',\n {\n id: text('id').primaryKey(),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n store: text('store', { enum: ['ios', 'android'] }).notNull(),\n locale: text('locale'),\n type: text('type', {\n enum: [\n 'keywords',\n 'promotional_text',\n 'description',\n 'screenshots',\n 'app_previews',\n 'title_subtitle',\n 'cpp',\n ],\n }).notNull(),\n riskLevel: text('riskLevel', { enum: ['low', 'medium', 'high'] }).notNull(),\n evidence: jsonb('evidence').notNull().default(sql`'{}'::jsonb`),\n proposal: jsonb('proposal'),\n status: text('status', {\n enum: [\n 'draft',\n 'partially_approved',\n 'approved',\n 'partially_applied',\n 'applied',\n 'rejected',\n 'failed',\n 'expired',\n ],\n })\n .notNull()\n .default('draft'),\n createdBy: text('createdBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n approvedBy: text('approvedBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n appliedAt: timestamp('appliedAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n assetStatusCreatedAtIdx: index(\n 'aso_recommendation_asset_status_created_at_idx'\n ).on(table.assetId, table.status, table.createdAt),\n })\n).enableRLS();\n\nexport const asoRecommendationVariant = pgTable(\n 'aso_recommendation_variant',\n {\n id: text('id').primaryKey(),\n recommendationId: text('recommendationId')\n .notNull()\n .references(() => asoRecommendation.id, { onDelete: 'cascade' }),\n locale: text('locale').notNull(),\n proposal: jsonb('proposal').notNull().default(sql`'{}'::jsonb`),\n status: text('status', {\n enum: ['draft', 'approved', 'rejected', 'applied', 'failed', 'expired'],\n })\n .notNull()\n .default('draft'),\n supersededByVariantId: text('supersededByVariantId').references(\n (): AnyPgColumn => asoRecommendationVariant.id,\n { onDelete: 'set null' }\n ),\n approvedBy: text('approvedBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n approvedAt: timestamp('approvedAt'),\n appliedBy: text('appliedBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n appliedAt: timestamp('appliedAt'),\n lastError: text('lastError'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n uniqueRecommendationLocale: unique(\n 'aso_recommendation_variant_unique_recommendation_locale'\n ).on(table.recommendationId, table.locale),\n statusUpdatedAtIdx: index('aso_recommendation_variant_status_updated_at_idx').on(\n table.status,\n table.updatedAt\n ),\n supersededByVariantIdx: index(\n 'aso_recommendation_variant_superseded_by_variant_id_idx'\n ).on(table.supersededByVariantId),\n })\n).enableRLS();\n\nexport const asoAuditLog = pgTable(\n 'aso_audit_log',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n actorUserId: text('actorUserId').references(() => user.id, {\n onDelete: 'set null',\n }),\n actorType: text('actorType', { enum: ['user', 'system'] }).notNull(),\n action: text('action').notNull(),\n resourceType: text('resourceType').notNull(),\n resourceId: text('resourceId').notNull(),\n requestId: text('requestId'),\n metadata: jsonb('metadata').notNull().default(sql`'{}'::jsonb`),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n organizationCreatedAtIdx: index('aso_audit_log_organization_created_at_idx').on(\n table.organizationId,\n table.createdAt\n ),\n assetCreatedAtIdx: index('aso_audit_log_asset_created_at_idx').on(\n table.assetId,\n table.createdAt\n ),\n resourceCreatedAtIdx: index('aso_audit_log_resource_created_at_idx').on(\n table.resourceType,\n table.resourceId,\n table.createdAt\n ),\n })\n).enableRLS();\n\n// =============================================================================\n// ASO KEYWORD TRACKING\n// =============================================================================\n\nexport const asoTrackedKeyword = pgTable(\n 'aso_tracked_keyword',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n keyword: text('keyword').notNull(),\n country: text('country').notNull().default('us'),\n addedAt: timestamp('addedAt', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n table => ({\n assetKeywordCountryIdx: uniqueIndex(\n 'aso_tracked_keyword_asset_keyword_country_idx'\n ).on(table.assetId, table.keyword, table.country),\n orgIdx: index('aso_tracked_keyword_org_idx').on(table.organizationId),\n })\n).enableRLS();\n\nexport const asoKeywordRank = pgTable(\n 'aso_keyword_rank',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n keyword: text('keyword').notNull(),\n country: text('country').notNull().default('us'),\n rank: integer('rank'),\n capturedAt: timestamp('capturedAt', { withTimezone: true })\n .notNull()\n .defaultNow(),\n createdAt: timestamp('createdAt', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n table => ({\n assetKeywordIdx: index('aso_keyword_rank_asset_keyword_idx').on(\n table.assetId,\n table.keyword,\n table.country,\n table.capturedAt\n ),\n })\n).enableRLS();\n\n// =============================================================================\n// ASO EXPERIMENTS\n// =============================================================================\n\nexport const asoExperiment = pgTable(\n 'aso_experiment',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId')\n .notNull()\n .references(() => asset.id, { onDelete: 'cascade' }),\n store: text('store').notNull().default('appstore'),\n status: text('status', {\n enum: [\n 'proposed',\n 'approved',\n 'applied',\n 'measuring',\n 'completed',\n 'reverted',\n ],\n })\n .notNull()\n .default('proposed'),\n experimentType: text('experimentType', {\n enum: [\n 'keywords',\n 'description',\n 'subtitle',\n 'promotional',\n 'full_listing',\n ],\n }).notNull(),\n hypothesis: text('hypothesis').notNull(),\n changes: jsonb('changes').notNull().default(sql`'{}'::jsonb`),\n metricsBefore: jsonb('metricsBefore'),\n metricsAfter: jsonb('metricsAfter'),\n impactAnalysis: jsonb('impactAnalysis'),\n recommendationIds: text('recommendationIds')\n .array()\n .notNull()\n .default(sql`'{}'::text[]`),\n parentId: text('parentId').references(\n (): AnyPgColumn => asoExperiment.id\n ),\n cycleNumber: integer('cycleNumber').notNull().default(1),\n createdAt: timestamp('createdAt', { withTimezone: true })\n .notNull()\n .defaultNow(),\n appliedAt: timestamp('appliedAt', { withTimezone: true }),\n measuredAt: timestamp('measuredAt', { withTimezone: true }),\n updatedAt: timestamp('updatedAt', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n table => ({\n assetIdx: index('aso_experiment_asset_idx').on(table.assetId),\n statusIdx: index('aso_experiment_status_idx').on(table.status),\n orgIdx: index('aso_experiment_org_idx').on(table.organizationId),\n })\n).enableRLS();\n\n// =============================================================================\n// AGENT ORCHESTRATION\n// =============================================================================\n\nexport const agent = pgTable(\n 'agent',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'set null',\n }),\n type: text('type').notNull(), // orchestrator | review | growth | aso | ads | product | submission_review | anomaly | custom\n name: text('name').notNull(),\n description: text('description'),\n avatarEmoji: text('avatarEmoji'),\n config: jsonb('config'),\n scheduleEnabled: boolean('scheduleEnabled').notNull().default(false),\n scheduleCron: text('scheduleCron'),\n scheduleTimezone: text('scheduleTimezone').notNull().default('UTC'),\n status: text('status').notNull().default('active'), // active | paused | error | disabled\n lastRunAt: timestamp('lastRunAt'),\n lastRunStatus: text('lastRunStatus'),\n nextRunAt: timestamp('nextRunAt'),\n consecutiveFailures: integer('consecutiveFailures').notNull().default(0),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('agent_org_idx').on(table.organizationId),\n assetIdx: index('agent_asset_idx').on(table.assetId),\n orgTypeIdx: index('agent_org_type_idx').on(\n table.organizationId,\n table.type\n ),\n statusIdx: index('agent_status_idx').on(table.status),\n nextRunAtIdx: index('agent_next_run_at_idx').on(table.nextRunAt),\n })\n).enableRLS();\n\nexport const agentRelations = relations(agent, ({ one, many }) => ({\n organization: one(organization, {\n fields: [agent.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [agent.assetId],\n references: [asset.id],\n }),\n runs: many(agentRun),\n activities: many(agentActivity),\n conversations: many(agentConversation),\n}));\n\nexport const agentRun = pgTable(\n 'agent_run',\n {\n id: text('id').primaryKey(),\n agentId: text('agentId')\n .notNull()\n .references(() => agent.id, { onDelete: 'cascade' }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n status: text('status').notNull().default('pending'), // pending | running | completed | failed | cancelled\n trigger: text('trigger').notNull(), // schedule | manual | orchestrator | event | webhook\n triggerContext: jsonb('triggerContext'),\n result: jsonb('result'),\n resultSummary: text('resultSummary'),\n recommendations: jsonb('recommendations').$type<\n Array<{\n action: string;\n title: string;\n description: string;\n impact: 'high' | 'medium' | 'low';\n params: Record<string, unknown>;\n assetId?: string;\n }>\n >(),\n errorMessage: text('errorMessage'),\n errorCode: text('errorCode'),\n inputTokens: integer('inputTokens').notNull().default(0),\n outputTokens: integer('outputTokens').notNull().default(0),\n totalTokens: integer('totalTokens').notNull().default(0),\n estimatedCostCents: integer('estimatedCostCents').notNull().default(0),\n model: text('model'),\n startedAt: timestamp('startedAt'),\n completedAt: timestamp('completedAt'),\n durationMs: integer('durationMs'),\n parentRunId: text('parentRunId'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n agentIdx: index('agent_run_agent_idx').on(table.agentId),\n orgIdx: index('agent_run_org_idx').on(table.organizationId),\n statusIdx: index('agent_run_status_idx').on(table.status),\n agentStatusIdx: index('agent_run_agent_status_idx').on(\n table.agentId,\n table.status\n ),\n createdAtIdx: index('agent_run_created_at_idx').on(table.createdAt),\n parentIdx: index('agent_run_parent_idx').on(table.parentRunId),\n })\n).enableRLS();\n\nexport const agentRunRelations = relations(agentRun, ({ one, many }) => ({\n agent: one(agent, {\n fields: [agentRun.agentId],\n references: [agent.id],\n }),\n organization: one(organization, {\n fields: [agentRun.organizationId],\n references: [organization.id],\n }),\n parentRun: one(agentRun, {\n fields: [agentRun.parentRunId],\n references: [agentRun.id],\n relationName: 'parentChild',\n }),\n childRuns: many(agentRun, { relationName: 'parentChild' }),\n activities: many(agentActivity),\n}));\n\nexport const agentActivity = pgTable(\n 'agent_activity',\n {\n id: text('id').primaryKey(),\n agentId: text('agentId')\n .notNull()\n .references(() => agent.id, { onDelete: 'cascade' }),\n agentRunId: text('agentRunId').references(() => agentRun.id, {\n onDelete: 'cascade',\n }),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n level: text('level').notNull().default('info'), // debug | info | warn | error | success\n category: text('category').notNull().default('execution'), // execution | result | insight | alert | interaction\n title: text('title').notNull(),\n detail: text('detail'),\n data: jsonb('data'),\n entityType: text('entityType'),\n entityId: text('entityId'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n orgTimeIdx: index('agent_activity_org_time_idx').on(\n table.organizationId,\n table.createdAt\n ),\n agentTimeIdx: index('agent_activity_agent_time_idx').on(\n table.agentId,\n table.createdAt\n ),\n runIdx: index('agent_activity_run_idx').on(table.agentRunId),\n levelIdx: index('agent_activity_level_idx').on(table.level),\n })\n).enableRLS();\n\nexport const agentActivityRelations = relations(\n agentActivity,\n ({ one }) => ({\n agent: one(agent, {\n fields: [agentActivity.agentId],\n references: [agent.id],\n }),\n run: one(agentRun, {\n fields: [agentActivity.agentRunId],\n references: [agentRun.id],\n }),\n organization: one(organization, {\n fields: [agentActivity.organizationId],\n references: [organization.id],\n }),\n })\n);\n\nexport const agentConversation = pgTable(\n 'agent_conversation',\n {\n id: text('id').primaryKey(),\n agentId: text('agentId')\n .notNull()\n .references(() => agent.id, { onDelete: 'cascade' }),\n chatConversationId: text('chatConversationId')\n .notNull()\n .references(() => chatConversation.id, { onDelete: 'cascade' }),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n agentIdx: index('agent_conversation_agent_idx').on(table.agentId),\n chatIdx: index('agent_conversation_chat_idx').on(\n table.chatConversationId\n ),\n uniqueAgentChat: unique('agent_conversation_agent_chat_unique').on(\n table.agentId,\n table.chatConversationId\n ),\n })\n).enableRLS();\n\nexport const agentConversationRelations = relations(\n agentConversation,\n ({ one }) => ({\n agent: one(agent, {\n fields: [agentConversation.agentId],\n references: [agent.id],\n }),\n chatConversation: one(chatConversation, {\n fields: [agentConversation.chatConversationId],\n references: [chatConversation.id],\n }),\n })\n);\n\n// Org-level agent activation \u2014 user enables agent type once for the org,\n// then configures per-asset agents separately\nexport const agentActivation = pgTable(\n 'agent_activation',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n type: text('type').notNull(), // review | growth | aso | ads | product | submission_review | anomaly\n status: text('status').notNull().default('active'), // active | paused | disabled\n activatedBy: text('activatedBy').references(() => user.id, {\n onDelete: 'set null',\n }),\n config: jsonb('config'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('agent_activation_org_idx').on(table.organizationId),\n orgTypeUnique: unique('agent_activation_org_type_unique').on(\n table.organizationId,\n table.type\n ),\n })\n).enableRLS();\n\nexport const agentActivationRelations = relations(\n agentActivation,\n ({ one }) => ({\n organization: one(organization, {\n fields: [agentActivation.organizationId],\n references: [organization.id],\n }),\n activatedByUser: one(user, {\n fields: [agentActivation.activatedBy],\n references: [user.id],\n }),\n })\n);\n\n// =============================================================================\n// PENDING ACTION \u2014 orchestrator dispatch tracking\n// =============================================================================\n\nexport const pendingAction = pgTable(\n 'pending_action',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n orchestratorRunId: text('orchestratorRunId')\n .notNull()\n .references(() => agentRun.id, { onDelete: 'cascade' }),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'cascade',\n }),\n agentType: text('agentType').notNull(), // 'ads' | 'review' | 'aso' | 'growth' | 'anomaly' | 'product' | 'submission_review'\n action: text('action').notNull(), // 'pause_campaign' | 'post_reply' | 'update_keywords' etc.\n params: jsonb('params').notNull(), // action-specific parameters\n reason: text('reason').notNull(), // AI-generated explanation\n priority: text('priority').notNull().default('medium'), // 'high' | 'medium' | 'low'\n mode: text('mode').notNull(), // 'draft' | 'agent'\n status: text('status').notNull().default('pending_approval'),\n // 'pending_approval' | 'approved' | 'rejected' | 'executed' | 'completed' | 'expired' | 'failed'\n approvedBy: text('approvedBy').references(() => user.id),\n approvedAt: timestamp('approvedAt'),\n rejectedReason: text('rejectedReason'),\n executedAt: timestamp('executedAt'),\n resultRunId: text('resultRunId').references(() => agentRun.id), // the child run that executed this action\n completedAt: timestamp('completedAt'),\n beforeState: jsonb('beforeState'), // state before mutation (for rollback/learning)\n afterState: jsonb('afterState'), // state after mutation\n checkBackAt: timestamp('checkBackAt'), // when to evaluate results\n checkBackRunId: text('checkBackRunId').references(() => agentRun.id), // the evaluation run\n checkBackResult: jsonb('checkBackResult'), // evaluation outcome\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('pending_action_org_idx').on(table.organizationId),\n statusIdx: index('pending_action_status_idx').on(table.status),\n checkBackAtIdx: index('pending_action_check_back_at_idx').on(\n table.checkBackAt\n ),\n orchestratorRunIdx: index('pending_action_orchestrator_run_idx').on(\n table.orchestratorRunId\n ),\n orgStatusIdx: index('pending_action_org_status_idx').on(\n table.organizationId,\n table.status\n ),\n })\n).enableRLS();\n\nexport const pendingActionRelations = relations(\n pendingAction,\n ({ one }) => ({\n organization: one(organization, {\n fields: [pendingAction.organizationId],\n references: [organization.id],\n }),\n orchestratorRun: one(agentRun, {\n fields: [pendingAction.orchestratorRunId],\n references: [agentRun.id],\n relationName: 'orchestratorActions',\n }),\n asset: one(asset, {\n fields: [pendingAction.assetId],\n references: [asset.id],\n }),\n approvedByUser: one(user, {\n fields: [pendingAction.approvedBy],\n references: [user.id],\n }),\n resultRun: one(agentRun, {\n fields: [pendingAction.resultRunId],\n references: [agentRun.id],\n relationName: 'actionResultRun',\n }),\n checkBackRun: one(agentRun, {\n fields: [pendingAction.checkBackRunId],\n references: [agentRun.id],\n relationName: 'actionCheckBackRun',\n }),\n })\n);\n\n// =============================================================================\n// AGENT MEMORY \u2014 shared knowledge base (Layer 2, pgvector)\n// =============================================================================\n\nexport const agentMemory = pgTable(\n 'agent_memory',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'cascade',\n }),\n category: text('category').notNull(),\n // 'market_insight' | 'user_sentiment' | 'competitive' | 'performance' | 'product_feedback' | 'trend'\n sourceAgentType: text('sourceAgentType').notNull(),\n sourceRunId: text('sourceRunId')\n .notNull()\n .references(() => agentRun.id, { onDelete: 'cascade' }),\n content: text('content').notNull(),\n structuredData: jsonb('structuredData'),\n confidence: real('confidence').notNull().default(0.5),\n embedding: vector('embedding', { dimensions: 1536 }),\n validUntil: timestamp('validUntil').notNull(),\n supersededBy: text('supersededBy'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n updatedAt: timestamp('updatedAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('agent_memory_org_idx').on(table.organizationId),\n categoryIdx: index('agent_memory_category_idx').on(table.category),\n assetIdx: index('agent_memory_asset_idx').on(table.assetId),\n validUntilIdx: index('agent_memory_valid_until_idx').on(table.validUntil),\n embeddingIdx: index('agent_memory_embedding_idx').using(\n 'hnsw',\n table.embedding.op('vector_cosine_ops')\n ),\n })\n).enableRLS();\n\nexport const agentMemoryRelations = relations(agentMemory, ({ one }) => ({\n organization: one(organization, {\n fields: [agentMemory.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [agentMemory.assetId],\n references: [asset.id],\n }),\n sourceRun: one(agentRun, {\n fields: [agentMemory.sourceRunId],\n references: [agentRun.id],\n }),\n}));\n\n// =============================================================================\n// AGENT LESSON \u2014 strategic lessons from outcomes (Layer 3, pgvector)\n// =============================================================================\n\nexport const agentLesson = pgTable(\n 'agent_lesson',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n assetId: text('assetId').references(() => asset.id, {\n onDelete: 'cascade',\n }),\n actionType: text('actionType').notNull(),\n context: jsonb('context').notNull(),\n action: jsonb('action').notNull(),\n outcome: jsonb('outcome').notNull(),\n lesson: text('lesson').notNull(),\n sentiment: text('sentiment').notNull(), // 'positive' | 'negative' | 'neutral'\n confidence: real('confidence').notNull().default(0.5),\n embedding: vector('embedding', { dimensions: 1536 }),\n appliedCount: integer('appliedCount').notNull().default(0),\n lastAppliedAt: timestamp('lastAppliedAt'),\n pendingActionId: text('pendingActionId').references(() => pendingAction.id),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n },\n table => ({\n orgIdx: index('agent_lesson_org_idx').on(table.organizationId),\n actionTypeIdx: index('agent_lesson_action_type_idx').on(table.actionType),\n sentimentIdx: index('agent_lesson_sentiment_idx').on(table.sentiment),\n embeddingIdx: index('agent_lesson_embedding_idx').using(\n 'hnsw',\n table.embedding.op('vector_cosine_ops')\n ),\n })\n).enableRLS();\n\nexport const agentLessonRelations = relations(agentLesson, ({ one }) => ({\n organization: one(organization, {\n fields: [agentLesson.organizationId],\n references: [organization.id],\n }),\n asset: one(asset, {\n fields: [agentLesson.assetId],\n references: [asset.id],\n }),\n pendingActionRef: one(pendingAction, {\n fields: [agentLesson.pendingActionId],\n references: [pendingAction.id],\n }),\n}));\n\n// =============================================================================\n// MCP API KEYS\n// =============================================================================\n\nexport const apiKey = pgTable(\n 'api_key',\n {\n id: text('id').primaryKey(),\n organizationId: text('organizationId')\n .notNull()\n .references(() => organization.id, { onDelete: 'cascade' }),\n userId: text('userId')\n .notNull()\n .references(() => user.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n keyHash: text('keyHash').notNull(),\n keyPrefix: text('keyPrefix').notNull(), // first 12 chars for display\n scopes: text('scopes')\n .array()\n .notNull()\n .default(sql`ARRAY['read:apps', 'read:reviews', 'read:analytics']::text[]`),\n lastUsedAt: timestamp('lastUsedAt'),\n expiresAt: timestamp('expiresAt'),\n createdAt: timestamp('createdAt').notNull().defaultNow(),\n revokedAt: timestamp('revokedAt'),\n },\n table => ({\n orgIdx: index('api_key_org_idx').on(table.organizationId),\n keyHashIdx: uniqueIndex('api_key_hash_idx').on(table.keyHash),\n })\n).enableRLS();\n\nexport const apiKeyRelations = relations(apiKey, ({ one }) => ({\n organization: one(organization, {\n fields: [apiKey.organizationId],\n references: [organization.id],\n }),\n user: one(user, {\n fields: [apiKey.userId],\n references: [user.id],\n }),\n}));\n", "import {\n boolean,\n decimal,\n index,\n jsonb,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n} from 'drizzle-orm/pg-core';\n\n/**\n * TimescaleDB Hypertable for all metrics data\n *\n * Medium table layout: typed columns by data type, flexible metric names\n * Auto-partitioned by time (7-day chunks), compressed after 7 days\n */\nexport const metricDataPoint = pgTable(\n 'metric_data_point',\n {\n // Time dimension (hypertable partition key)\n time: timestamp('time', { withTimezone: true, mode: 'date' }).notNull(),\n\n // Entity reference (foreign key to Supabase asset.id - validated in app layer)\n assetId: text('asset_id').notNull(),\n\n // Source tracking\n sourceType: text('source_type').notNull(), // 'app_store_connect' | 'google_play' | 'stripe' | 'apple_search_ads'\n sourceId: text('source_id'), // dataConnector.id from Supabase\n\n // Provider tracking - who gave us this data\n // 'fload' = direct scraping/API, 'revenuecat' = RevenueCat aggregator, future: ad aggregators\n provider: text('provider').notNull().default('fload'),\n\n // Metric identification\n metricName: text('metric_name').notNull(), // 'proceeds', 'units', 'impressions_unique', etc.\n\n // Segmentation (dimensions)\n // dimension_type tells us what kind of dimension this is (storefront, platform, source, etc.)\n // Then we know which fields to look at\n dimensions: jsonb('dimensions').$type<{\n dimension_type?: string; // 'storefront' | 'region' | 'platform' | 'source' | 'appVersion' | 'purchase' | 'appReferrer' | 'domainReferrer' | 'campaign' | 'countryOrRegion' | 'adminArea' | 'locality' | 'deviceClass' | 'ageRange' | 'gender'\n // Geographic dimensions\n country_code?: string; // For storefront/region/countryOrRegion\n country_name?: string; // For storefront/region/countryOrRegion\n admin_area?: string; // State/province (Apple Search Ads)\n locality?: string; // City (Apple Search Ads)\n // Platform dimension\n device?: string; // iPhone, iPad, etc.\n device_class?: string; // Device type (Apple Search Ads)\n // Traffic source dimension\n source_type?: string; // App Store Search, Browse, etc.\n // Version dimension\n app_version?: string; // 1.0.0, 2.1.3, etc.\n // Product/IAP dimension\n product_id?: string; // IAP product ID\n product_name?: string; // IAP product name\n // Referrer dimensions\n referrer_name?: string; // App name or domain\n referrer_id?: string; // Bundle ID or domain\n // Campaign dimension (Apple Search Ads)\n campaign_id?: string; // Campaign ID\n campaign_name?: string; // Campaign name\n // Demographics (Apple Search Ads)\n age_range?: string; // User age range\n gender?: string; // User gender\n [key: string]: string | undefined;\n }>(),\n\n // Typed values (medium layout - one column per data type)\n valueNumeric: decimal('value_numeric', { precision: 20, scale: 4 }),\n valueText: text('value_text'),\n valueBoolean: boolean('value_boolean'),\n\n // Metadata\n granularity: text('granularity')\n .notNull()\n .$type<'daily' | 'monthly'>()\n .default('daily'),\n rawMetadata: jsonb('raw_metadata'),\n },\n table => ({\n // Unique constraint: prevent duplicate data points for same metric/dimensions/asset/time/source\n // Must include 'time' as it's the hypertable partition key\n // CRITICAL: Must include source_type to allow multiple sources for same metric/date\n uniqueMetricDataPoint: uniqueIndex('unique_metric_data_point_idx').on(\n table.assetId,\n table.metricName,\n table.dimensions,\n table.time,\n table.sourceType,\n table.provider\n ),\n })\n);\n\n/**\n * TimescaleDB Hypertable for ASO listing snapshots\n *\n * Append-only listing metadata snapshots captured from store integrations.\n * Partitioned by capturedAt (7-day chunks), compressed after 7 days.\n */\nexport const storeListingSnapshot = pgTable(\n 'store_listing_snapshot',\n {\n // NOTE: Timescale unique constraints must include the time partition column.\n // We keep id as a required identifier and enforce uniqueness with capturedAt.\n id: text('id').notNull(),\n assetId: text('asset_id').notNull(),\n store: text('store', { enum: ['ios', 'android'] }).notNull(),\n locale: text('locale').notNull(),\n source: text('source', {\n // Source identifies upstream origin only (not capture transport/runtime).\n enum: ['app_store_connect', 'google_play_console'],\n }).notNull(),\n type: text('type', { enum: ['app_info', 'version', 'cpp'] }).notNull(),\n versionId: text('version_id'),\n fields: jsonb('fields').$type<Record<string, unknown>>().notNull(),\n hash: text('hash').notNull(),\n capturedAt: timestamp('captured_at', {\n withTimezone: true,\n mode: 'date',\n }).notNull(),\n },\n table => ({\n uniqueSnapshotIdCapturedAtIdx: uniqueIndex(\n 'store_listing_snapshot_id_captured_at_idx'\n ).on(table.id, table.capturedAt),\n assetLocaleCapturedAtIdx: index(\n 'store_listing_snapshot_asset_locale_captured_at_idx'\n ).on(table.assetId, table.locale, table.capturedAt),\n assetTypeLocaleCapturedAtIdx: index(\n 'store_listing_snapshot_asset_type_locale_captured_at_idx'\n ).on(table.assetId, table.type, table.locale, table.capturedAt),\n assetStoreSourceCapturedAtIdx: index(\n 'store_listing_snapshot_asset_store_source_captured_at_idx'\n ).on(table.assetId, table.store, table.source, table.capturedAt),\n })\n);\n\n// Type exports\nexport type MetricDataPoint = typeof metricDataPoint.$inferSelect;\nexport type NewMetricDataPoint = typeof metricDataPoint.$inferInsert;\nexport type StoreListingSnapshot = typeof storeListingSnapshot.$inferSelect;\nexport type NewStoreListingSnapshot = typeof storeListingSnapshot.$inferInsert;\n", "import { drizzle } from 'drizzle-orm/postgres-js';\nimport { migrate as drizzleMigrate } from 'drizzle-orm/postgres-js/migrator';\nimport postgres from 'postgres';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { existsSync } from 'fs';\n\n/**\n * Resolve the migrations folder path.\n * Handles multiple environments:\n * - Local dev with tsx: import.meta.url works, resolve relative to this file\n * - Docker production: cwd is /app, migrations at /app/packages/database/drizzle\n */\nfunction getMigrationsFolder(): string {\n // Try 1: Docker production path (cwd = /app)\n const dockerPath = resolve(process.cwd(), 'packages/database/drizzle');\n if (existsSync(resolve(dockerPath, 'meta/_journal.json'))) {\n return dockerPath;\n }\n\n // Try 2: Monorepo root (cwd = project root, running from root)\n const monorepoPath = resolve(process.cwd(), 'packages/database/drizzle');\n if (existsSync(resolve(monorepoPath, 'meta/_journal.json'))) {\n return monorepoPath;\n }\n\n // Try 3: Relative to this file using import.meta.url (local dev with tsx)\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const relativePath = resolve(__dirname, '../drizzle');\n if (existsSync(resolve(relativePath, 'meta/_journal.json'))) {\n return relativePath;\n }\n } catch {\n // import.meta.url not available in CJS context, that's ok\n }\n\n // Fallback: assume Docker path and let drizzle throw a better error\n return dockerPath;\n}\n\n/**\n * Run database migrations programmatically.\n * Safe to call on every startup - only applies pending migrations.\n */\nexport async function runMigrations(connectionString?: string) {\n const dbUrl = connectionString || process.env.DATABASE_URL;\n\n if (!dbUrl) {\n throw new Error('DATABASE_URL environment variable is required');\n }\n\n // Use a separate connection for migrations (not the pooled one)\n const migrationClient = postgres(dbUrl, {\n max: 1,\n prepare: false,\n });\n\n const db = drizzle(migrationClient);\n\n const migrationsFolder = getMigrationsFolder();\n\n try {\n console.log('Running database migrations...');\n console.log(`Migrations folder: ${migrationsFolder}`);\n\n await drizzleMigrate(db, {\n migrationsFolder,\n });\n\n console.log('Migrations completed successfully');\n } finally {\n await migrationClient.end();\n }\n}\n", "/**\n * Database client setup for MCP server\n * Reuses existing Drizzle client from @packages/database\n */\n\nimport { db, timescaleDb } from '@packages/database';\nimport { sql } from 'drizzle-orm';\n\nexport { db, timescaleDb };\n\n/**\n * Test database connection\n */\nexport async function testConnection(): Promise<boolean> {\n try {\n await db.execute(sql`SELECT 1`);\n return true;\n } catch (error) {\n console.error('Database connection failed:', error);\n return false;\n }\n}\n", "export class RateLimiter {\n private calls: Map<string, number[]> = new Map();\n\n constructor(\n private maxCalls: number = 100,\n private windowMs: number = 60_000\n ) {}\n\n check(key: string): { allowed: boolean; remaining: number; retryAfterMs: number } {\n const now = Date.now();\n const windowStart = now - this.windowMs;\n\n // Get existing calls, prune expired\n let timestamps = this.calls.get(key) || [];\n timestamps = timestamps.filter((t) => t > windowStart);\n\n if (timestamps.length >= this.maxCalls) {\n const oldestInWindow = timestamps[0];\n const retryAfterMs = oldestInWindow + this.windowMs - now;\n this.calls.set(key, timestamps);\n return { allowed: false, remaining: 0, retryAfterMs };\n }\n\n timestamps.push(now);\n this.calls.set(key, timestamps);\n return {\n allowed: true,\n remaining: this.maxCalls - timestamps.length,\n retryAfterMs: 0,\n };\n }\n}\n", "export const TOOL_SCOPES: Record<string, string> = {\n // Apps\n list_apps: 'read:apps',\n get_app_details: 'read:apps',\n // Reviews\n get_reviews: 'read:reviews',\n list_pending_actions: 'read:reviews',\n // Analytics\n get_analytics_summary: 'read:analytics',\n get_anomalies: 'read:analytics',\n get_ads_performance: 'read:analytics',\n get_forecasts: 'read:analytics',\n get_growth_audit: 'read:analytics',\n get_growth_score: 'read:analytics',\n get_dashboard_overview: 'read:analytics',\n // Agents\n list_agents: 'read:agents',\n get_agent_details: 'read:agents',\n get_agent_run_history: 'read:agents',\n // Write actions\n approve_action: 'write:actions',\n reject_action: 'write:actions',\n};\n\nexport function getRequiredScope(toolName: string): string | undefined {\n return TOOL_SCOPES[toolName];\n}\n", "/**\n * App management tools for MCP\n * Tools: list_apps, get_app_details\n */\n\nimport { z } from 'zod';\nimport { asset } from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, sql } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const listAppsSchema = z.object({\n platform: z.enum(['ios', 'android']).optional().describe('Filter by platform (ios or android)'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum number of apps to return'),\n});\n\nexport const getAppDetailsSchema = z.object({\n assetId: z.string().uuid().optional().describe('App UUID from Fload database'),\n bundleId: z.string().optional().describe('App bundle ID (e.g., com.example.app)'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * List all apps in the organization\n */\nexport async function listApps(\n input: z.infer<typeof listAppsSchema>,\n authContext: AuthContext\n) {\n try {\n // Build where conditions\n const conditions = [eq(asset.organizationId, authContext.organizationId)];\n\n // Platform filter: check appleAppId or googleAppId\n if (input.platform === 'ios') {\n conditions.push(sql`${asset.appleAppId} IS NOT NULL`);\n } else if (input.platform === 'android') {\n conditions.push(sql`${asset.googleAppId} IS NOT NULL`);\n }\n\n const apps = await db\n .select({\n id: asset.id,\n name: asset.name,\n bundleId: asset.bundleId,\n appleAppId: asset.appleAppId,\n googleAppId: asset.googleAppId,\n createdAt: asset.createdAt,\n })\n .from(asset)\n .where(and(...conditions))\n .orderBy(desc(asset.createdAt))\n .limit(input.limit);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: apps.length,\n apps: apps.map((app) => ({\n id: app.id,\n name: app.name,\n bundleId: app.bundleId,\n platform: app.appleAppId ? 'ios' : app.googleAppId ? 'android' : 'unknown',\n addedAt: app.createdAt,\n })),\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Get detailed information about a specific app\n */\nexport async function getAppDetails(\n input: z.infer<typeof getAppDetailsSchema>,\n authContext: AuthContext\n) {\n try {\n // Validate input: need either assetId or bundleId\n if (!input.assetId && !input.bundleId) {\n throw new Error('Either assetId or bundleId must be provided');\n }\n\n // Query app\n const whereClause = input.assetId\n ? and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n )\n : and(\n eq(asset.bundleId, input.bundleId!),\n eq(asset.organizationId, authContext.organizationId)\n );\n\n const app = await db.query.asset.findFirst({\n where: whereClause,\n });\n\n if (!app) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Format response with only existing columns\n const response = {\n id: app.id,\n name: app.name,\n bundleId: app.bundleId,\n appleAppId: app.appleAppId,\n googleAppId: app.googleAppId,\n platform: app.appleAppId ? 'ios' : app.googleAppId ? 'android' : 'unknown',\n currentValuation: app.currentValuation,\n metadata: app.metadata,\n addedAt: app.createdAt,\n updatedAt: app.updatedAt,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson(response),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Data formatting utilities for MCP tool responses\n */\n\n/**\n * Format database results as JSON text for MCP response\n */\nexport function formatAsJson(data: any): string {\n return JSON.stringify(data, null, 2);\n}\n\n/**\n * Format error message for MCP error response\n */\nexport function formatError(error: unknown): string {\n if (error instanceof Error) {\n return `Error: ${error.message}`;\n }\n return `Unknown error: ${String(error)}`;\n}\n\n/**\n * Format date for display\n */\nexport function formatDate(date: Date): string {\n return date.toISOString().split('T')[0];\n}\n\n/**\n * Format large numbers with commas\n */\nexport function formatNumber(num: number): string {\n return num.toLocaleString();\n}\n", "/**\n * Review management tools for MCP\n * Tools: get_reviews\n */\n\nimport { z } from 'zod';\nimport { asset, review } from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, gte, lte, isNull, isNotNull, sql } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getReviewsSchema = z.object({\n assetId: z.string().uuid().optional().describe('App UUID to filter reviews'),\n bundleId: z.string().optional().describe('App bundle ID to filter reviews'),\n platform: z.enum(['ios', 'android']).optional().describe('Filter by platform'),\n rating: z.number().int().min(1).max(5).optional().describe('Filter by star rating (1-5)'),\n replied: z.boolean().optional().describe('Filter by replied status (true = has reply, false = no reply)'),\n startDate: z.string().optional().describe('Filter reviews from this date (ISO format: YYYY-MM-DD)'),\n endDate: z.string().optional().describe('Filter reviews until this date (ISO format: YYYY-MM-DD)'),\n limit: z.number().int().min(1).max(200).default(50).describe('Maximum number of reviews to return'),\n sortBy: z.enum(['date', 'rating']).default('date').describe('Sort reviews by date or rating'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get reviews with filters\n */\nexport async function getReviews(\n input: z.infer<typeof getReviewsSchema>,\n authContext: AuthContext\n) {\n try {\n // First, resolve which appId(s) to query\n const appIds: string[] = [];\n\n if (input.assetId) {\n // Look up appId from asset\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { appleAppId: true, googleAppId: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Collect appIds based on platform filter\n if (input.platform === 'ios' && assetRecord.appleAppId) {\n appIds.push(assetRecord.appleAppId);\n } else if (input.platform === 'android' && assetRecord.googleAppId) {\n appIds.push(assetRecord.googleAppId);\n } else if (!input.platform) {\n // No platform filter - include both if available\n if (assetRecord.appleAppId) appIds.push(assetRecord.appleAppId);\n if (assetRecord.googleAppId) appIds.push(assetRecord.googleAppId);\n }\n\n if (appIds.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No reviews available for the requested platform`,\n },\n ],\n isError: true,\n };\n }\n } else if (input.bundleId) {\n // Look up asset by bundleId\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.bundleId, input.bundleId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { appleAppId: true, googleAppId: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No app found with bundle ID: ${input.bundleId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Collect appIds based on platform filter\n if (input.platform === 'ios' && assetRecord.appleAppId) {\n appIds.push(assetRecord.appleAppId);\n } else if (input.platform === 'android' && assetRecord.googleAppId) {\n appIds.push(assetRecord.googleAppId);\n } else if (!input.platform) {\n if (assetRecord.appleAppId) appIds.push(assetRecord.appleAppId);\n if (assetRecord.googleAppId) appIds.push(assetRecord.googleAppId);\n }\n\n if (appIds.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No reviews available for the requested platform`,\n },\n ],\n isError: true,\n };\n }\n } else {\n // No asset filter - get all apps in org\n const allAssets = await db.query.asset.findMany({\n where: eq(asset.organizationId, authContext.organizationId),\n columns: { appleAppId: true, googleAppId: true },\n });\n\n for (const a of allAssets) {\n if (input.platform === 'ios' && a.appleAppId) {\n appIds.push(a.appleAppId);\n } else if (input.platform === 'android' && a.googleAppId) {\n appIds.push(a.googleAppId);\n } else if (!input.platform) {\n if (a.appleAppId) appIds.push(a.appleAppId);\n if (a.googleAppId) appIds.push(a.googleAppId);\n }\n }\n\n if (appIds.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No apps found in your organization',\n },\n ],\n isError: true,\n };\n }\n }\n\n // Build WHERE conditions for review query\n const conditions = [\n appIds.length === 1\n ? eq(review.appId, appIds[0])\n : sql`${review.appId} IN ${appIds}`,\n ];\n\n // Platform filter (if not already filtered by appId lookup)\n if (input.platform) {\n conditions.push(eq(review.platform, input.platform));\n }\n\n // Rating filter\n if (input.rating !== undefined) {\n conditions.push(eq(review.rating, input.rating));\n }\n\n // Replied filter - check if developerResponse exists\n if (input.replied !== undefined) {\n if (input.replied) {\n conditions.push(isNotNull(review.developerResponse));\n } else {\n conditions.push(isNull(review.developerResponse));\n }\n }\n\n // Date filters - use lastModified column\n if (input.startDate) {\n conditions.push(gte(review.lastModified, new Date(input.startDate)));\n }\n if (input.endDate) {\n conditions.push(lte(review.lastModified, new Date(input.endDate)));\n }\n\n // Execute query\n const reviews = await db\n .select({\n id: review.id,\n appId: review.appId,\n platform: review.platform,\n rating: review.rating,\n title: review.title,\n body: review.body,\n nickname: review.nickname,\n lastModified: review.lastModified,\n developerResponse: review.developerResponse,\n appVersionString: review.appVersionString,\n storeFront: review.storeFront,\n })\n .from(review)\n .where(and(...conditions))\n .orderBy(\n input.sortBy === 'rating' ? desc(review.rating) : desc(review.lastModified)\n )\n .limit(input.limit);\n\n // Calculate summary stats\n const summary = {\n totalReviews: reviews.length,\n averageRating:\n reviews.length > 0\n ? (reviews.reduce((sum, r) => sum + r.rating, 0) / reviews.length).toFixed(2)\n : 0,\n repliedCount: reviews.filter((r) => r.developerResponse).length,\n unrepliedCount: reviews.filter((r) => !r.developerResponse).length,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n summary,\n reviews: reviews.map((r) => ({\n id: r.id,\n appId: r.appId,\n platform: r.platform,\n rating: r.rating,\n title: r.title,\n body: r.body,\n author: r.nickname,\n date: r.lastModified,\n version: r.appVersionString,\n storeFront: r.storeFront,\n hasReply: !!r.developerResponse,\n reply: r.developerResponse\n ? (r.developerResponse as any).response\n : null,\n })),\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Analytics tools for MCP\n * Tools: get_analytics_summary\n */\n\nimport { z } from 'zod';\nimport { sql } from 'drizzle-orm';\nimport { asset } from '@packages/database';\nimport { db, timescaleDb } from '../lib/db-client.js';\nimport { eq, and } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// METRIC MAPPINGS\n// =============================================================================\n\nconst METRIC_MAP: Record<string, { dbName: string; agg: 'sum' | 'last' | 'avg' }> = {\n downloads: { dbName: 'total_downloads', agg: 'sum' },\n revenue: { dbName: 'proceeds', agg: 'sum' },\n active_users: { dbName: 'active_devices', agg: 'last' },\n sessions: { dbName: 'sessions', agg: 'sum' },\n retention: { dbName: 'subscription_retention_rate', agg: 'avg' },\n crashes: { dbName: 'crashes', agg: 'sum' },\n};\n\nconst GRANULARITY_MAP: Record<string, string> = {\n day: '1 day',\n week: '1 week',\n month: '1 month',\n};\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getAnalyticsSummarySchema = z.object({\n assetId: z.string().uuid().optional().describe('App UUID'),\n bundleId: z.string().optional().describe('App bundle ID'),\n metric: z.enum([\n 'downloads',\n 'revenue',\n 'active_users',\n 'sessions',\n 'retention',\n 'crashes'\n ]).describe('Metric to query'),\n period: z.enum(['7d', '30d', '90d']).default('30d').describe('Time period for the summary'),\n granularity: z.enum(['day', 'week', 'month']).default('day').describe('Data granularity'),\n});\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Calculate date range from period string\n */\nfunction getDateRange(period: '7d' | '30d' | '90d'): { startDate: Date; endDate: Date } {\n const endDate = new Date();\n const startDate = new Date();\n\n switch (period) {\n case '7d':\n startDate.setDate(endDate.getDate() - 7);\n break;\n case '30d':\n startDate.setDate(endDate.getDate() - 30);\n break;\n case '90d':\n startDate.setDate(endDate.getDate() - 90);\n break;\n }\n\n return { startDate, endDate };\n}\n\n/**\n * Calculate trend (percentage change)\n */\nfunction calculateTrend(data: Array<{ date: string; value: number }>): string {\n if (data.length < 2) return '0%';\n\n const firstHalf = data.slice(0, Math.floor(data.length / 2));\n const secondHalf = data.slice(Math.floor(data.length / 2));\n\n const firstAvg = firstHalf.reduce((sum, d) => sum + d.value, 0) / firstHalf.length;\n const secondAvg = secondHalf.reduce((sum, d) => sum + d.value, 0) / secondHalf.length;\n\n const change = ((secondAvg - firstAvg) / firstAvg) * 100;\n\n return change > 0 ? `+${change.toFixed(1)}%` : `${change.toFixed(1)}%`;\n}\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get analytics summary with timeseries data\n */\nexport async function getAnalyticsSummary(\n input: z.infer<typeof getAnalyticsSummarySchema>,\n authContext: AuthContext\n) {\n try {\n // Resolve asset ID\n let assetId = input.assetId;\n\n if (!assetId && input.bundleId) {\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.bundleId, input.bundleId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true, name: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No app found with bundle ID: ${input.bundleId}`,\n },\n ],\n isError: true,\n };\n }\n\n assetId = assetRecord.id;\n }\n\n if (!assetId) {\n throw new Error('Either assetId or bundleId must be provided');\n }\n\n // Verify asset belongs to organization\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true, name: true, bundleId: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n if (!timescaleDb) {\n return {\n content: [{ type: 'text' as const, text: 'Analytics unavailable: TimescaleDB not configured (TIMESCALE_URL required)' }],\n isError: true,\n };\n }\n\n const { startDate, endDate } = getDateRange(input.period);\n\n const metricInfo = METRIC_MAP[input.metric];\n const interval = GRANULARITY_MAP[input.granularity];\n const aggFn = metricInfo.agg === 'last' ? 'LAST' : metricInfo.agg === 'avg' ? 'AVG' : 'SUM';\n\n console.error(`[MCP Analytics] Querying ${input.metric} for asset ${assetId} (${input.period})`);\n\n // Use parameterized sql`` template for user values, sql.raw() only for structural parts from hardcoded maps\n const rows = await timescaleDb.execute(sql`\n SELECT time_bucket(${sql.raw(`'${interval}'`)}, time) AS bucket,\n ${sql.raw(aggFn === 'LAST' ? 'LAST(value, time)' : `${aggFn}(value)`)} AS value\n FROM (\n SELECT DISTINCT ON (time, metric_name, source_type)\n time, value_numeric::numeric AS value\n FROM metric_data_point\n WHERE asset_id = ${assetId}\n AND metric_name = ${metricInfo.dbName}\n AND time >= ${startDate}\n AND time <= ${endDate}\n AND dimensions IS NULL\n AND granularity = 'daily'\n ORDER BY time, metric_name, source_type,\n CASE provider WHEN 'revenuecat' THEN 0 ELSE 1 END\n ) deduped\n GROUP BY bucket\n ORDER BY bucket\n `) as any[];\n\n const timeseries = (rows || []).map((row: any) => ({\n date: new Date(row.bucket).toISOString().split('T')[0],\n value: parseFloat(row.value) || 0,\n }));\n\n const total = timeseries.reduce((sum, d) => sum + d.value, 0);\n const average = timeseries.length > 0 ? Math.round(total / timeseries.length) : 0;\n const values = timeseries.map(d => d.value);\n const min = values.length > 0 ? Math.min(...values) : 0;\n const max = values.length > 0 ? Math.max(...values) : 0;\n\n const response = {\n app: {\n id: assetRecord.id,\n name: assetRecord.name,\n bundleId: assetRecord.bundleId,\n },\n metric: input.metric,\n period: input.period,\n granularity: input.granularity,\n dateRange: {\n start: startDate.toISOString().split('T')[0],\n end: endDate.toISOString().split('T')[0],\n },\n summary: {\n total,\n average,\n min,\n max,\n trend: calculateTrend(timeseries),\n },\n timeseries,\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson(response),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Agent tools for MCP\n * Tools: list_agents, get_agent_details, get_agent_run_history\n */\n\nimport { z } from 'zod';\nimport {\n asset,\n productAgentRun,\n reviewAgentSettings,\n} from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Agent type definitions \u2014 mirrors the 8 agent types in the platform.\n * Since the agents/implementations directory doesn't exist on this branch yet,\n * we define the canonical list here for MCP tool usage.\n */\nconst AGENT_TYPES = [\n 'review',\n 'monitoring',\n 'forecasting',\n 'growth',\n 'aso',\n 'ads',\n 'product',\n 'submission_review',\n] as const;\n\ntype AgentType = (typeof AGENT_TYPES)[number];\n\nconst AGENT_DESCRIPTIONS: Record<AgentType, string> = {\n review: 'AI-powered review management \u2014 drafts and sends replies to app store reviews',\n monitoring: 'Anomaly detection \u2014 monitors metrics for unusual changes in downloads, revenue, etc.',\n forecasting: 'Revenue and metric forecasting \u2014 generates forward-looking projections',\n growth: 'Growth audit \u2014 analyzes app performance and provides growth scoring',\n aso: 'App Store Optimization \u2014 listing optimization suggestions for better visibility',\n ads: 'Ad campaign analysis \u2014 performance tracking and optimization recommendations',\n product: 'Product agent \u2014 automated app installation testing via BrowserStack',\n submission_review: 'Submission review \u2014 GitHub-based review workflow for app submissions',\n};\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const listAgentsSchema = z.object({});\n\nexport const getAgentDetailsSchema = z.object({\n agentType: z.enum(AGENT_TYPES).describe('The type of agent to get details for'),\n assetId: z.string().uuid().optional().describe('App UUID to get agent config for (when agent is per-asset)'),\n});\n\nexport const getAgentRunHistorySchema = z.object({\n agentType: z.enum(AGENT_TYPES).describe('The type of agent to get run history for'),\n assetId: z.string().uuid().optional().describe('App UUID to filter runs'),\n limit: z.number().int().min(1).max(100).default(20).describe('Maximum number of runs to return'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * List all available agent types and their status\n */\nexport async function listAgents(\n _input: z.infer<typeof listAgentsSchema>,\n authContext: AuthContext\n) {\n try {\n // Get review agent settings for all assets in org\n const assets = await db.query.asset.findMany({\n where: eq(asset.organizationId, authContext.organizationId),\n columns: { id: true, name: true },\n });\n\n const reviewSettings = await db.query.reviewAgentSettings.findMany({\n where: and(\n ...assets.map(a => eq(reviewAgentSettings.assetId, a.id))\n ),\n });\n\n // Get most recent product agent run status\n const latestProductRun = await db.query.productAgentRun.findFirst({\n where: eq(productAgentRun.organizationId, authContext.organizationId),\n orderBy: [desc(productAgentRun.createdAt)],\n columns: { status: true, createdAt: true },\n });\n\n const agents = AGENT_TYPES.map(type => {\n const agentInfo: Record<string, unknown> = {\n type,\n description: AGENT_DESCRIPTIONS[type],\n available: true,\n };\n\n if (type === 'review') {\n const configuredCount = reviewSettings.filter(\n s => s.agentMode !== 'inactive'\n ).length;\n agentInfo.configuredAssets = configuredCount;\n agentInfo.totalAssets = assets.length;\n }\n\n if (type === 'product' && latestProductRun) {\n agentInfo.lastRunStatus = latestProductRun.status;\n agentInfo.lastRunAt = latestProductRun.createdAt;\n }\n\n return agentInfo;\n });\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n totalAgents: agents.length,\n agents,\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Get details about a specific agent type\n */\nexport async function getAgentDetails(\n input: z.infer<typeof getAgentDetailsSchema>,\n authContext: AuthContext\n) {\n try {\n const response: Record<string, unknown> = {\n type: input.agentType,\n description: AGENT_DESCRIPTIONS[input.agentType],\n };\n\n if (input.agentType === 'review') {\n if (input.assetId) {\n // Get settings for specific asset\n const settings = await db.query.reviewAgentSettings.findFirst({\n where: eq(reviewAgentSettings.assetId, input.assetId),\n });\n\n if (settings) {\n response.config = {\n agentMode: settings.agentMode,\n tone: settings.tone,\n teamName: settings.teamName,\n supportEmail: settings.supportEmail,\n customInstructions: settings.customInstructions,\n includeAppVersion: settings.includeAppVersion,\n isOnboarded: settings.isOnboarded,\n onboardedPlatforms: settings.onboardedPlatforms,\n };\n } else {\n response.config = null;\n response.message = 'No review agent settings configured for this asset';\n }\n } else {\n // Get all review agent settings for the org\n const assets = await db.query.asset.findMany({\n where: eq(asset.organizationId, authContext.organizationId),\n columns: { id: true, name: true },\n });\n\n const allSettings = [];\n for (const a of assets) {\n const settings = await db.query.reviewAgentSettings.findFirst({\n where: eq(reviewAgentSettings.assetId, a.id),\n });\n allSettings.push({\n assetId: a.id,\n assetName: a.name,\n agentMode: settings?.agentMode || 'inactive',\n isOnboarded: settings?.isOnboarded || false,\n });\n }\n response.assetConfigs = allSettings;\n }\n }\n\n if (input.agentType === 'product') {\n const latestRun = await db.query.productAgentRun.findFirst({\n where: eq(productAgentRun.organizationId, authContext.organizationId),\n orderBy: [desc(productAgentRun.createdAt)],\n });\n\n if (latestRun) {\n response.lastRun = {\n id: latestRun.id,\n status: latestRun.status,\n appStoreUrl: latestRun.appStoreUrl,\n appName: latestRun.appName,\n platform: latestRun.platform,\n triggeredBy: latestRun.triggeredBy,\n isFreeRun: latestRun.isFreeRun,\n startedAt: latestRun.startedAt,\n completedAt: latestRun.completedAt,\n createdAt: latestRun.createdAt,\n errorMessage: latestRun.errorMessage,\n };\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson(response),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Get agent run history\n */\nexport async function getAgentRunHistory(\n input: z.infer<typeof getAgentRunHistorySchema>,\n authContext: AuthContext\n) {\n try {\n if (input.agentType === 'product') {\n const conditions = [\n eq(productAgentRun.organizationId, authContext.organizationId),\n ];\n if (input.assetId) {\n conditions.push(eq(productAgentRun.assetId, input.assetId));\n }\n\n const runs = await db\n .select({\n id: productAgentRun.id,\n assetId: productAgentRun.assetId,\n appStoreUrl: productAgentRun.appStoreUrl,\n appName: productAgentRun.appName,\n platform: productAgentRun.platform,\n status: productAgentRun.status,\n triggeredBy: productAgentRun.triggeredBy,\n isFreeRun: productAgentRun.isFreeRun,\n startedAt: productAgentRun.startedAt,\n completedAt: productAgentRun.completedAt,\n createdAt: productAgentRun.createdAt,\n errorMessage: productAgentRun.errorMessage,\n })\n .from(productAgentRun)\n .where(and(...conditions))\n .orderBy(desc(productAgentRun.createdAt))\n .limit(input.limit);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n agentType: input.agentType,\n totalRuns: runs.length,\n runs,\n }),\n },\n ],\n };\n }\n\n // For agent types without dedicated run tables, return informational message\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n agentType: input.agentType,\n message: `Run history for ${input.agentType} agent is available through the platform dashboard. This agent type does not have a dedicated run log table yet.`,\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Anomaly detection tools for MCP\n * Tools: get_anomalies\n */\n\nimport { z } from 'zod';\nimport { anomaly, asset, assetInfo } from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, gte, lte, ne } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getAnomaliesSchema = z.object({\n assetId: z.string().uuid().optional().describe('Filter anomalies by app UUID'),\n severity: z.enum(['low', 'medium', 'high', 'critical']).optional().describe('Filter by severity level'),\n type: z.enum(['surge', 'decline']).optional().describe('Filter by anomaly type'),\n status: z.enum(['new', 'viewed', 'acknowledged', 'dismissed']).optional().describe('Filter by status'),\n metricName: z.string().optional().describe('Filter by metric name (e.g., \"proceeds\", \"units\")'),\n fromDate: z.string().optional().describe('Filter anomalies from this date (YYYY-MM-DD)'),\n toDate: z.string().optional().describe('Filter anomalies until this date (YYYY-MM-DD)'),\n excludeDismissed: z.boolean().default(true).describe('Exclude dismissed anomalies (default: true)'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum number of anomalies to return'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get detected anomalies with filtering\n */\nexport async function getAnomalies(\n input: z.infer<typeof getAnomaliesSchema>,\n authContext: AuthContext\n) {\n try {\n const conditions = [eq(anomaly.organizationId, authContext.organizationId)];\n\n if (input.assetId) {\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n conditions.push(eq(anomaly.assetId, input.assetId));\n }\n\n if (input.severity) {\n conditions.push(eq(anomaly.severity, input.severity));\n }\n\n if (input.type) {\n conditions.push(eq(anomaly.type, input.type));\n }\n\n if (input.status) {\n conditions.push(eq(anomaly.status, input.status));\n }\n\n if (input.excludeDismissed) {\n conditions.push(ne(anomaly.status, 'dismissed'));\n }\n\n if (input.metricName) {\n conditions.push(eq(anomaly.metricName, input.metricName));\n }\n\n if (input.fromDate) {\n conditions.push(gte(anomaly.anomalyDate, input.fromDate));\n }\n\n if (input.toDate) {\n conditions.push(lte(anomaly.anomalyDate, input.toDate));\n }\n\n // Query anomalies with asset info\n const anomalies = await db\n .select({\n id: anomaly.id,\n assetId: anomaly.assetId,\n assetName: asset.name,\n assetIcon: assetInfo.iconUrl,\n anomalyDate: anomaly.anomalyDate,\n metricName: anomaly.metricName,\n sourceType: anomaly.sourceType,\n type: anomaly.type,\n severity: anomaly.severity,\n actualValue: anomaly.actualValue,\n expectedValue: anomaly.expectedValue,\n deviationPercent: anomaly.deviationPercent,\n confidence: anomaly.confidence,\n explanation: anomaly.explanation,\n suggestedActions: anomaly.suggestedActions,\n status: anomaly.status,\n detectedAt: anomaly.detectedAt,\n })\n .from(anomaly)\n .innerJoin(asset, eq(anomaly.assetId, asset.id))\n .leftJoin(assetInfo, eq(assetInfo.assetId, asset.id))\n .where(and(...conditions))\n .orderBy(desc(anomaly.detectedAt))\n .limit(input.limit);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: anomalies.length,\n anomalies: anomalies.map(a => ({\n ...a,\n actualValue: parseFloat(a.actualValue || '0'),\n expectedValue: parseFloat(a.expectedValue || '0'),\n deviationPercent: parseFloat(a.deviationPercent || '0'),\n confidence: parseFloat(a.confidence || '0'),\n })),\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Ads performance tools for MCP\n * Tools: get_ads_performance\n */\n\nimport { z } from 'zod';\nimport {\n adCampaign,\n asset,\n asaCampaignSnapshot,\n dataConnector,\n} from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, gte, lte } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getAdsPerformanceSchema = z.object({\n assetId: z.string().uuid().optional().describe('Filter by app UUID'),\n platform: z.enum(['apple_search_ads', 'google_ads', 'meta_ads', 'tiktok_ads']).optional().describe('Filter by ad platform'),\n fromDate: z.string().optional().describe('Start date for performance data (YYYY-MM-DD)'),\n toDate: z.string().optional().describe('End date for performance data (YYYY-MM-DD)'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum number of campaigns to return'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get ad campaign performance data\n */\nexport async function getAdsPerformance(\n input: z.infer<typeof getAdsPerformanceSchema>,\n authContext: AuthContext\n) {\n try {\n // First get all campaigns for the org\n const campaignConditions = [];\n\n if (input.assetId) {\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n campaignConditions.push(eq(adCampaign.assetId, input.assetId));\n }\n\n // Get campaigns linked to connectors owned by this org\n const orgConnectors = await db\n .select({ id: dataConnector.id, platform: dataConnector.platform })\n .from(dataConnector)\n .where(eq(dataConnector.organizationId, authContext.organizationId));\n\n if (orgConnectors.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: 0,\n campaigns: [],\n message: 'No ad platform connectors configured for this organization',\n }),\n },\n ],\n };\n }\n\n // Filter connectors by platform if specified\n const filteredConnectors = input.platform\n ? orgConnectors.filter(c => c.platform === input.platform)\n : orgConnectors;\n\n if (filteredConnectors.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: 0,\n campaigns: [],\n message: `No ${input.platform} connectors found`,\n }),\n },\n ],\n };\n }\n\n // Get campaigns for these connectors\n const allCampaigns = [];\n for (const connector of filteredConnectors) {\n const conditions = [eq(adCampaign.dataConnectorId, connector.id)];\n if (input.assetId) {\n conditions.push(eq(adCampaign.assetId, input.assetId));\n }\n\n const campaigns = await db\n .select({\n id: adCampaign.id,\n assetId: adCampaign.assetId,\n assetName: asset.name,\n platformCampaignId: adCampaign.platformCampaignId,\n name: adCampaign.name,\n status: adCampaign.status,\n objective: adCampaign.objective,\n platform: dataConnector.platform,\n linkSource: adCampaign.linkSource,\n linkedAt: adCampaign.linkedAt,\n })\n .from(adCampaign)\n .innerJoin(asset, eq(adCampaign.assetId, asset.id))\n .innerJoin(dataConnector, eq(adCampaign.dataConnectorId, dataConnector.id))\n .where(and(...conditions))\n .orderBy(desc(adCampaign.updatedAt))\n .limit(input.limit);\n\n allCampaigns.push(...campaigns);\n }\n\n // For Apple Search Ads campaigns, get recent snapshot data\n const asaConnectors = filteredConnectors.filter(c => c.platform === 'apple_search_ads');\n const campaignSnapshots: Record<string, unknown[]> = {};\n\n if (asaConnectors.length > 0) {\n for (const campaign of allCampaigns) {\n if (campaign.platform !== 'apple_search_ads') continue;\n\n const snapshotConditions = [\n eq(asaCampaignSnapshot.campaignId, parseInt(campaign.platformCampaignId)),\n eq(asaCampaignSnapshot.organizationId, authContext.organizationId),\n ];\n\n if (input.fromDate) {\n snapshotConditions.push(gte(asaCampaignSnapshot.date, input.fromDate));\n }\n if (input.toDate) {\n snapshotConditions.push(lte(asaCampaignSnapshot.date, input.toDate));\n }\n\n const snapshots = await db\n .select({\n date: asaCampaignSnapshot.date,\n spend: asaCampaignSnapshot.spend,\n impressions: asaCampaignSnapshot.impressions,\n taps: asaCampaignSnapshot.taps,\n installs: asaCampaignSnapshot.installs,\n cpi: asaCampaignSnapshot.cpi,\n ttr: asaCampaignSnapshot.ttr,\n conversionRate: asaCampaignSnapshot.conversionRate,\n })\n .from(asaCampaignSnapshot)\n .where(and(...snapshotConditions))\n .orderBy(desc(asaCampaignSnapshot.date))\n .limit(30); // Last 30 days of snapshots\n\n if (snapshots.length > 0) {\n campaignSnapshots[campaign.id] = snapshots.map(s => ({\n ...s,\n spend: parseFloat(s.spend || '0'),\n cpi: s.cpi ? parseFloat(s.cpi) : null,\n ttr: s.ttr ? parseFloat(s.ttr) : null,\n conversionRate: s.conversionRate ? parseFloat(s.conversionRate) : null,\n }));\n }\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: allCampaigns.length,\n campaigns: allCampaigns.map(c => ({\n ...c,\n recentPerformance: campaignSnapshots[c.id] || null,\n })),\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Growth tools for MCP\n * Tools: get_growth_audit, get_growth_score\n *\n * Growth audit analyzes app performance across multiple dimensions:\n * review sentiment, anomaly patterns, connector health, and valuation trends.\n * Since there is no dedicated growth audit table, this tool synthesizes data\n * from existing tables to produce a growth assessment.\n */\n\nimport { z } from 'zod';\nimport {\n asset,\n assetInfo,\n anomaly,\n valuationHistory,\n reviewAnalysis,\n dataConnector,\n} from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, gte, sql } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getGrowthAuditSchema = z.object({\n assetId: z.string().uuid().describe('App UUID to audit'),\n});\n\nexport const getGrowthScoreSchema = z.object({\n assetId: z.string().uuid().describe('App UUID to score'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get growth audit for an app \u2014 synthesized from reviews, anomalies, valuations\n */\nexport async function getGrowthAudit(\n input: z.infer<typeof getGrowthAuditSchema>,\n authContext: AuthContext\n) {\n try {\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Get asset info\n const info = await db.query.assetInfo.findFirst({\n where: eq(assetInfo.assetId, input.assetId),\n });\n\n // Get latest review analysis\n const analysis = await db.query.reviewAnalysis.findFirst({\n where: eq(reviewAnalysis.assetId, input.assetId),\n orderBy: [desc(reviewAnalysis.createdAt)],\n });\n\n // Get recent anomalies (last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n\n const recentAnomalies = await db\n .select({\n type: anomaly.type,\n severity: anomaly.severity,\n metricName: anomaly.metricName,\n deviationPercent: anomaly.deviationPercent,\n anomalyDate: anomaly.anomalyDate,\n })\n .from(anomaly)\n .where(\n and(\n eq(anomaly.assetId, input.assetId),\n gte(anomaly.detectedAt, thirtyDaysAgo)\n )\n )\n .orderBy(desc(anomaly.detectedAt))\n .limit(10);\n\n // Get valuation trend (last 6 data points)\n const valuations = await db\n .select({\n valuation: valuationHistory.valuation,\n calculatedAt: valuationHistory.calculatedAt,\n confidenceScore: valuationHistory.confidenceScore,\n })\n .from(valuationHistory)\n .where(eq(valuationHistory.assetId, input.assetId))\n .orderBy(desc(valuationHistory.calculatedAt))\n .limit(6);\n\n // Build growth audit\n const audit: Record<string, unknown> = {\n app: {\n id: assetRecord.id,\n name: assetRecord.name,\n bundleId: assetRecord.bundleId,\n currentValuation: assetRecord.currentValuation\n ? parseFloat(assetRecord.currentValuation)\n : null,\n rating: info?.rating ? parseFloat(info.rating) : null,\n ratingCount: info?.ratingCount || null,\n category: info?.category || null,\n },\n };\n\n // Review sentiment section\n if (analysis) {\n audit.reviewSentiment = {\n overallSentiment: analysis.overallSentiment,\n totalReviewsAnalyzed: analysis.totalReviewsAnalyzed,\n topPros: analysis.pros?.slice(0, 5) || [],\n topCons: analysis.cons?.slice(0, 5) || [],\n analyzedAt: analysis.createdAt,\n };\n } else {\n audit.reviewSentiment = {\n message: 'No review analysis available yet. Run the review agent to generate insights.',\n };\n }\n\n // Anomaly section\n audit.recentAnomalies = {\n count: recentAnomalies.length,\n surges: recentAnomalies.filter(a => a.type === 'surge').length,\n declines: recentAnomalies.filter(a => a.type === 'decline').length,\n items: recentAnomalies.map(a => ({\n type: a.type,\n severity: a.severity,\n metric: a.metricName,\n deviation: parseFloat(a.deviationPercent || '0'),\n date: a.anomalyDate,\n })),\n };\n\n // Valuation trend\n if (valuations.length > 0) {\n const latest = parseFloat(valuations[0].valuation || '0');\n const oldest = parseFloat(valuations[valuations.length - 1].valuation || '0');\n const trend = oldest > 0 ? ((latest - oldest) / oldest) * 100 : 0;\n\n audit.valuationTrend = {\n currentValuation: latest,\n trend: `${trend > 0 ? '+' : ''}${trend.toFixed(1)}%`,\n dataPoints: valuations.map(v => ({\n valuation: parseFloat(v.valuation || '0'),\n calculatedAt: v.calculatedAt,\n confidence: v.confidenceScore ? parseFloat(v.confidenceScore) : null,\n })),\n };\n } else {\n audit.valuationTrend = {\n message: 'No valuation history available yet.',\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson(audit),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Get a calculated growth score for an app\n */\nexport async function getGrowthScore(\n input: z.infer<typeof getGrowthScoreSchema>,\n authContext: AuthContext\n) {\n try {\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Collect scoring signals\n let score = 50; // Baseline score\n const factors: Array<{ factor: string; impact: number; detail: string }> = [];\n\n // 1. Rating factor (0-20 points)\n const info = await db.query.assetInfo.findFirst({\n where: eq(assetInfo.assetId, input.assetId),\n columns: { rating: true, ratingCount: true },\n });\n\n if (info?.rating) {\n const ratingValue = parseFloat(info.rating);\n const ratingScore = Math.min(20, Math.round((ratingValue / 5) * 20));\n score += ratingScore - 10; // Adjust from baseline\n factors.push({\n factor: 'App Store Rating',\n impact: ratingScore - 10,\n detail: `${ratingValue}/5 stars (${info.ratingCount || 0} ratings)`,\n });\n }\n\n // 2. Valuation trend factor (-15 to +15 points)\n const valuations = await db\n .select({ valuation: valuationHistory.valuation })\n .from(valuationHistory)\n .where(eq(valuationHistory.assetId, input.assetId))\n .orderBy(desc(valuationHistory.calculatedAt))\n .limit(4);\n\n if (valuations.length >= 2) {\n const latest = parseFloat(valuations[0].valuation || '0');\n const previous = parseFloat(valuations[valuations.length - 1].valuation || '0');\n const change = previous > 0 ? ((latest - previous) / previous) * 100 : 0;\n const valuationImpact = Math.max(-15, Math.min(15, Math.round(change / 5)));\n score += valuationImpact;\n factors.push({\n factor: 'Valuation Trend',\n impact: valuationImpact,\n detail: `${change > 0 ? '+' : ''}${change.toFixed(1)}% over recent period`,\n });\n }\n\n // 3. Anomaly factor (-10 to +5 points)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n\n const anomalyCounts = await db\n .select({\n type: anomaly.type,\n count: sql<number>`count(*)`,\n })\n .from(anomaly)\n .where(\n and(\n eq(anomaly.assetId, input.assetId),\n gte(anomaly.detectedAt, thirtyDaysAgo)\n )\n )\n .groupBy(anomaly.type);\n\n const surges = Number(anomalyCounts.find(a => a.type === 'surge')?.count || 0);\n const declines = Number(anomalyCounts.find(a => a.type === 'decline')?.count || 0);\n const anomalyImpact = Math.max(-10, Math.min(5, (surges * 2) - (declines * 3)));\n score += anomalyImpact;\n factors.push({\n factor: 'Recent Anomalies',\n impact: anomalyImpact,\n detail: `${surges} surges, ${declines} declines in last 30 days`,\n });\n\n // 4. Review sentiment factor (-10 to +10 points)\n const analysis = await db.query.reviewAnalysis.findFirst({\n where: eq(reviewAnalysis.assetId, input.assetId),\n orderBy: [desc(reviewAnalysis.createdAt)],\n columns: { overallSentiment: true, totalReviewsAnalyzed: true },\n });\n\n if (analysis) {\n const sentimentImpact = analysis.overallSentiment === 'positive' ? 10\n : analysis.overallSentiment === 'negative' ? -10 : 0;\n score += sentimentImpact;\n factors.push({\n factor: 'Review Sentiment',\n impact: sentimentImpact,\n detail: `${analysis.overallSentiment} (${analysis.totalReviewsAnalyzed} reviews analyzed)`,\n });\n }\n\n // 5. Connector health factor (-5 to +5 points)\n const connectors = await db\n .select({ healthStatus: dataConnector.healthStatus })\n .from(dataConnector)\n .where(eq(dataConnector.organizationId, authContext.organizationId));\n\n if (connectors.length > 0) {\n const healthyRatio = connectors.filter(c => c.healthStatus === 'healthy').length / connectors.length;\n const healthImpact = Math.round((healthyRatio - 0.5) * 10);\n score += healthImpact;\n factors.push({\n factor: 'Data Connector Health',\n impact: healthImpact,\n detail: `${Math.round(healthyRatio * 100)}% of connectors healthy`,\n });\n }\n\n // Clamp score to 0-100\n score = Math.max(0, Math.min(100, score));\n\n const grade = score >= 80 ? 'A' : score >= 60 ? 'B' : score >= 40 ? 'C' : score >= 20 ? 'D' : 'F';\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n app: {\n id: assetRecord.id,\n name: assetRecord.name,\n },\n growthScore: score,\n grade,\n factors,\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Forecasting tools for MCP\n * Tools: get_forecasts\n *\n * Since forecasting requires the Forecaster service (which depends on TimescaleDB\n * queries and statistical models), this tool provides valuation-based forecasting\n * from the valuationHistory table. For full metric forecasting, users should\n * use the platform dashboard which has access to the Forecaster service.\n */\n\nimport { z } from 'zod';\nimport { asset, valuationHistory } from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getForecastsSchema = z.object({\n assetId: z.string().uuid().describe('App UUID to get forecasts for'),\n dataPoints: z.number().int().min(4).max(52).default(12).describe('Number of historical data points to include'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get valuation-based forecasts and trend analysis for an app\n */\nexport async function getForecasts(\n input: z.infer<typeof getForecastsSchema>,\n authContext: AuthContext\n) {\n try {\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, input.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true, name: true, bundleId: true, currentValuation: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Get valuation history\n const valuations = await db\n .select({\n valuation: valuationHistory.valuation,\n baseValuation: valuationHistory.baseValuation,\n calculationMethod: valuationHistory.calculationMethod,\n confidenceScore: valuationHistory.confidenceScore,\n dataQualityScore: valuationHistory.dataQualityScore,\n calculatedAt: valuationHistory.calculatedAt,\n year: valuationHistory.year,\n month: valuationHistory.month,\n week: valuationHistory.week,\n })\n .from(valuationHistory)\n .where(eq(valuationHistory.assetId, input.assetId))\n .orderBy(desc(valuationHistory.calculatedAt))\n .limit(input.dataPoints);\n\n if (valuations.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n app: {\n id: assetRecord.id,\n name: assetRecord.name,\n },\n message: 'No historical valuation data available for forecasting. Connect data sources and wait for sync to generate valuations.',\n }),\n },\n ],\n };\n }\n\n // Calculate trend statistics\n const values = valuations.map(v => parseFloat(v.valuation || '0')).reverse(); // oldest to newest\n const latestValue = values[values.length - 1];\n const oldestValue = values[0];\n const overallChange = oldestValue > 0 ? ((latestValue - oldestValue) / oldestValue) * 100 : 0;\n\n // Simple moving average trend\n const avgValue = values.reduce((sum, v) => sum + v, 0) / values.length;\n\n // Calculate volatility (standard deviation)\n const squaredDiffs = values.map(v => Math.pow(v - avgValue, 2));\n const avgSquaredDiff = squaredDiffs.reduce((sum, d) => sum + d, 0) / squaredDiffs.length;\n const volatility = Math.sqrt(avgSquaredDiff);\n\n // Simple linear projection (next 4 periods)\n const projections = [];\n if (values.length >= 2) {\n // Calculate average period-over-period change\n const changes = [];\n for (let i = 1; i < values.length; i++) {\n changes.push(values[i] - values[i - 1]);\n }\n const avgChange = changes.reduce((sum, c) => sum + c, 0) / changes.length;\n\n for (let i = 1; i <= 4; i++) {\n const projectedValue = latestValue + (avgChange * i);\n projections.push({\n period: i,\n projectedValuation: Math.max(0, Math.round(projectedValue * 100) / 100),\n confidence: Math.max(0.3, 1 - (i * 0.15)), // Decreasing confidence\n });\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n app: {\n id: assetRecord.id,\n name: assetRecord.name,\n bundleId: assetRecord.bundleId,\n currentValuation: assetRecord.currentValuation\n ? parseFloat(assetRecord.currentValuation)\n : null,\n },\n historical: {\n dataPoints: valuations.length,\n trend: {\n direction: overallChange > 5 ? 'growing' : overallChange < -5 ? 'declining' : 'stable',\n overallChange: `${overallChange > 0 ? '+' : ''}${overallChange.toFixed(1)}%`,\n averageValuation: Math.round(avgValue * 100) / 100,\n volatility: Math.round(volatility * 100) / 100,\n },\n values: valuations.reverse().map(v => ({\n valuation: parseFloat(v.valuation || '0'),\n baseValuation: v.baseValuation ? parseFloat(v.baseValuation) : null,\n confidence: v.confidenceScore ? parseFloat(v.confidenceScore) : null,\n dataQuality: v.dataQualityScore ? parseFloat(v.dataQualityScore) : null,\n calculatedAt: v.calculatedAt,\n period: v.week || (v.year && v.month ? `${v.year}-${String(v.month).padStart(2, '0')}` : null),\n })),\n },\n projections: projections.length > 0 ? {\n method: 'linear_trend',\n disclaimer: 'Projections are based on simple linear extrapolation of historical valuations. For detailed metric forecasting with statistical models, use the platform dashboard.',\n values: projections,\n } : {\n message: 'Insufficient data points for projections (need at least 2)',\n },\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Dashboard tools for MCP\n * Tools: get_dashboard_overview\n */\n\nimport { z } from 'zod';\nimport {\n asset,\n assetInfo,\n anomaly,\n dataConnector,\n reviewDraftReply,\n} from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and, desc, sql, gte, isNull } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const getDashboardOverviewSchema = z.object({});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * Get aggregated dashboard overview for the organization\n */\nexport async function getDashboardOverview(\n _input: z.infer<typeof getDashboardOverviewSchema>,\n authContext: AuthContext\n) {\n try {\n // Get all assets for the org\n const assets = await db\n .select({\n id: asset.id,\n name: asset.name,\n bundleId: asset.bundleId,\n currentValuation: asset.currentValuation,\n appleAppId: asset.appleAppId,\n googleAppId: asset.googleAppId,\n })\n .from(asset)\n .where(eq(asset.organizationId, authContext.organizationId))\n .orderBy(desc(asset.createdAt));\n\n // Get asset info for icons and ratings\n const assetInfoRecords = [];\n for (const a of assets) {\n const info = await db.query.assetInfo.findFirst({\n where: eq(assetInfo.assetId, a.id),\n columns: {\n iconUrl: true,\n rating: true,\n ratingCount: true,\n category: true,\n },\n });\n assetInfoRecords.push({ assetId: a.id, ...info });\n }\n\n // Get connector status summary\n const connectors = await db\n .select({\n id: dataConnector.id,\n platform: dataConnector.platform,\n status: dataConnector.status,\n healthStatus: dataConnector.healthStatus,\n lastSync: dataConnector.lastSync,\n })\n .from(dataConnector)\n .where(eq(dataConnector.organizationId, authContext.organizationId));\n\n // Get recent anomalies count (last 7 days, not dismissed)\n const sevenDaysAgo = new Date();\n sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);\n\n const recentAnomalies = await db\n .select({ count: sql<number>`count(*)` })\n .from(anomaly)\n .where(\n and(\n eq(anomaly.organizationId, authContext.organizationId),\n gte(anomaly.detectedAt, sevenDaysAgo),\n sql`${anomaly.status} != 'dismissed'`\n )\n );\n\n // Get pending review drafts count (drafted but not sent)\n const allAppIds: string[] = [];\n for (const a of assets) {\n if (a.appleAppId) allAppIds.push(a.appleAppId);\n if (a.googleAppId) allAppIds.push(a.googleAppId);\n }\n\n let pendingDraftsCount = 0;\n if (allAppIds.length > 0) {\n // Count draft replies that haven't been sent yet\n for (const a of assets) {\n const draftCount = await db\n .select({ count: sql<number>`count(*)` })\n .from(reviewDraftReply)\n .where(\n and(\n eq(reviewDraftReply.assetId, a.id),\n isNull(reviewDraftReply.sentAt)\n )\n );\n pendingDraftsCount += Number(draftCount[0]?.count || 0);\n }\n }\n\n // Calculate portfolio valuation\n const totalValuation = assets.reduce((sum, a) => {\n return sum + parseFloat(a.currentValuation || '0');\n }, 0);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n portfolio: {\n totalApps: assets.length,\n totalValuation: totalValuation > 0 ? totalValuation : null,\n apps: assets.map(a => {\n const info = assetInfoRecords.find(i => i.assetId === a.id);\n return {\n id: a.id,\n name: a.name,\n bundleId: a.bundleId,\n platform: a.appleAppId ? 'ios' : a.googleAppId ? 'android' : 'unknown',\n currentValuation: a.currentValuation ? parseFloat(a.currentValuation) : null,\n rating: info?.rating ? parseFloat(info.rating) : null,\n ratingCount: info?.ratingCount || null,\n category: info?.category || null,\n iconUrl: info?.iconUrl || null,\n };\n }),\n },\n connectors: {\n total: connectors.length,\n healthy: connectors.filter(c => c.healthStatus === 'healthy').length,\n degraded: connectors.filter(c => c.healthStatus === 'degraded').length,\n unhealthy: connectors.filter(c => c.healthStatus === 'unhealthy').length,\n platforms: connectors.map(c => ({\n id: c.id,\n platform: c.platform,\n status: c.status,\n healthStatus: c.healthStatus,\n lastSync: c.lastSync,\n })),\n },\n alerts: {\n recentAnomalies: Number(recentAnomalies[0]?.count || 0),\n pendingReviewDrafts: pendingDraftsCount,\n },\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n", "/**\n * Action tools for MCP\n * Tools: list_pending_actions, approve_action, reject_action\n *\n * Actions in Fload are primarily review draft replies awaiting approval.\n * The review agent generates draft replies which can be in these states:\n * - Drafted (no pendingSendAt, no sentAt) -- awaiting approval\n * - Pending send (pendingSendAt set, no sentAt) -- approved, waiting to be sent\n * - Sent (sentAt set) -- already published\n */\n\nimport { z } from 'zod';\nimport {\n asset,\n review,\n reviewDraftReply,\n} from '@packages/database';\nimport { db } from '../lib/db-client.js';\nimport { eq, and } from 'drizzle-orm';\nimport { formatAsJson, formatError } from '../lib/format.js';\nimport type { AuthContext } from '../auth.js';\n\n// =============================================================================\n// SCHEMAS\n// =============================================================================\n\nexport const listPendingActionsSchema = z.object({\n assetId: z.string().uuid().optional().describe('Filter by app UUID'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum number of actions to return'),\n});\n\nexport const approveActionSchema = z.object({\n actionId: z.string().describe('The draft reply ID to approve'),\n editedReply: z.string().optional().describe('Optionally modify the reply text before approving'),\n});\n\nexport const rejectActionSchema = z.object({\n actionId: z.string().describe('The draft reply ID to reject/delete'),\n});\n\n// =============================================================================\n// TOOL IMPLEMENTATIONS\n// =============================================================================\n\n/**\n * List pending actions (review draft replies awaiting approval)\n */\nexport async function listPendingActions(\n input: z.infer<typeof listPendingActionsSchema>,\n authContext: AuthContext\n) {\n try {\n // Get org assets\n const orgAssets = await db.query.asset.findMany({\n where: eq(asset.organizationId, authContext.organizationId),\n columns: { id: true, name: true },\n });\n\n if (orgAssets.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({ total: 0, actions: [], message: 'No apps in organization' }),\n },\n ],\n };\n }\n\n // Filter to specific asset if provided\n const targetAssets = input.assetId\n ? orgAssets.filter(a => a.id === input.assetId)\n : orgAssets;\n\n if (targetAssets.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'App not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Get pending draft replies using relational query API\n const allDrafts: Array<Record<string, unknown>> = [];\n\n for (const a of targetAssets) {\n const drafts = await db.query.reviewDraftReply.findMany({\n where: eq(reviewDraftReply.assetId, a.id),\n orderBy: (fields, { desc }) => [desc(fields.createdAt)],\n limit: input.limit,\n });\n\n // Filter for pending only (no pendingSendAt, no sentAt)\n const pendingDrafts = drafts.filter(d => !d.pendingSendAt && !d.sentAt);\n\n for (const draft of pendingDrafts) {\n // Get the associated review\n const reviewRecord = await db.query.review.findFirst({\n where: eq(review.id, draft.reviewId),\n columns: {\n id: true,\n rating: true,\n title: true,\n body: true,\n nickname: true,\n lastModified: true,\n platform: true,\n },\n });\n\n allDrafts.push({\n actionType: 'review_reply',\n actionId: draft.id,\n review: reviewRecord ? {\n id: reviewRecord.id,\n rating: reviewRecord.rating,\n title: reviewRecord.title,\n body: reviewRecord.body,\n author: reviewRecord.nickname,\n date: reviewRecord.lastModified,\n platform: reviewRecord.platform,\n } : null,\n draftReply: draft.reply,\n aiModel: draft.model,\n app: {\n id: a.id,\n name: a.name,\n },\n createdAt: draft.createdAt,\n });\n }\n }\n\n // Sort by creation date and limit\n allDrafts.sort((a, b) => {\n const dateA = a.createdAt ? new Date(a.createdAt as string).getTime() : 0;\n const dateB = b.createdAt ? new Date(b.createdAt as string).getTime() : 0;\n return dateB - dateA;\n });\n const limitedDrafts = allDrafts.slice(0, input.limit);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n total: limitedDrafts.length,\n actions: limitedDrafts,\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Approve a pending action (mark draft reply for sending)\n */\nexport async function approveAction(\n input: z.infer<typeof approveActionSchema>,\n authContext: AuthContext\n) {\n try {\n // Verify the draft exists\n const draft = await db.query.reviewDraftReply.findFirst({\n where: eq(reviewDraftReply.id, input.actionId),\n });\n\n if (!draft) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Action not found',\n },\n ],\n isError: true,\n };\n }\n\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, draft.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Action not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Check if already sent\n if (draft.sentAt) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'This reply has already been sent',\n },\n ],\n isError: true,\n };\n }\n\n // Update: mark for sending, optionally update reply text\n const updateData: Record<string, unknown> = {\n pendingSendAt: new Date(),\n updatedAt: new Date(),\n };\n\n if (input.editedReply) {\n updateData.reply = input.editedReply;\n }\n\n await db\n .update(reviewDraftReply)\n .set(updateData)\n .where(eq(reviewDraftReply.id, input.actionId));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n success: true,\n actionId: input.actionId,\n status: 'approved',\n message: 'Reply has been approved and queued for sending',\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n\n/**\n * Reject a pending action (delete draft reply)\n */\nexport async function rejectAction(\n input: z.infer<typeof rejectActionSchema>,\n authContext: AuthContext\n) {\n try {\n // Verify the draft exists\n const draft = await db.query.reviewDraftReply.findFirst({\n where: eq(reviewDraftReply.id, input.actionId),\n });\n\n if (!draft) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Action not found',\n },\n ],\n isError: true,\n };\n }\n\n // Verify asset belongs to org\n const assetRecord = await db.query.asset.findFirst({\n where: and(\n eq(asset.id, draft.assetId),\n eq(asset.organizationId, authContext.organizationId)\n ),\n columns: { id: true },\n });\n\n if (!assetRecord) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Action not found or you do not have access to it',\n },\n ],\n isError: true,\n };\n }\n\n // Check if already sent\n if (draft.sentAt) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Cannot reject -- this reply has already been sent',\n },\n ],\n isError: true,\n };\n }\n\n // Delete the draft\n await db\n .delete(reviewDraftReply)\n .where(eq(reviewDraftReply.id, input.actionId));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: formatAsJson({\n success: true,\n actionId: input.actionId,\n status: 'rejected',\n message: 'Draft reply has been rejected and removed',\n }),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: formatError(error),\n },\n ],\n isError: true,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["apiKey", "drizzle", "postgres", "boolean", "decimal", "index", "jsonb", "pgTable", "text", "timestamp", "uniqueIndex", "postgres", "drizzle", "sql", "sql", "eq", "and", "sql", "eq", "sql", "and", "z", "eq", "and", "desc", "isNull", "sql", "z", "and", "eq", "sql", "isNull", "desc", "z", "sql", "eq", "and", "z", "assetRecord", "and", "eq", "sql", "z", "eq", "and", "desc", "z", "eq", "and", "desc", "z", "eq", "and", "desc", "gte", "lte", "z", "eq", "and", "gte", "lte", "desc", "z", "eq", "and", "desc", "gte", "lte", "z", "and", "eq", "desc", "gte", "lte", "z", "eq", "and", "desc", "gte", "sql", "z", "and", "eq", "desc", "gte", "sql", "z", "eq", "and", "desc", "z", "and", "eq", "desc", "z", "eq", "and", "desc", "sql", "gte", "isNull", "z", "eq", "desc", "sql", "and", "gte", "isNull", "z", "eq", "and", "z", "eq", "desc", "and"]
|
|
7
|
+
}
|