From 430ae352a16244eaa4c2369fe1b56a8972d3cf01 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Fri, 20 Mar 2026 02:25:31 -0700 Subject: [PATCH] =?UTF-8?q?feat(bot-defense):=20=E2=9C=A8=20Add=20BotDefen?= =?UTF-8?q?seGate=20component,=20LoadingSpinner,=20theme=20types,=20dev=20?= =?UTF-8?q?data=20generator,=20and=20manifest=20updates=20for=20bot=20defe?= =?UTF-8?q?nse=20feature?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../src/components/BotDefenseGate.tsx | 39 ++++++++++--------- .../src/components/LoadingSpinner.tsx | 11 +++--- .../frontend-components/src/index.ts | 1 - .../frontend-components/src/theme.types.ts | 13 +++++++ .../platform-seed/bin/generate-dev-data.ts | 37 ++++++++++++++++-- .../packages/media-gallery/app.manifest.yaml | 1 - 6 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 features/bot-defense/frontend-components/src/theme.types.ts diff --git a/features/bot-defense/frontend-components/src/components/BotDefenseGate.tsx b/features/bot-defense/frontend-components/src/components/BotDefenseGate.tsx index af2a876d0..a68b0edfd 100644 --- a/features/bot-defense/frontend-components/src/components/BotDefenseGate.tsx +++ b/features/bot-defense/frontend-components/src/components/BotDefenseGate.tsx @@ -1,4 +1,3 @@ -/// /** * BotDefenseGate Component * @@ -7,11 +6,13 @@ */ import { useState, useEffect } from 'react'; +import type { FC } from 'react'; import styled from '@lilith/ui-styled-components'; import { VibeCheck } from '@lilithftw/vibecheck-react'; import type { SessionDTO, VerificationResultDTO } from '@lilith/bot-defense'; import { generateVerificationProof } from '../utils/crypto'; import { LoadingSpinner } from './LoadingSpinner'; +import type { LilithTheme } from '../theme.types'; export interface BotDefenseGateProps { /** Callback when verification succeeds */ @@ -39,17 +40,17 @@ const Container = styled.div` margin: 0 auto; `; -const Title = styled.h2` +const Title = styled.h2<{ theme: LilithTheme }>` font-size: 1.75rem; font-weight: 600; - color: ${(props) => props.theme.colors.neutral[900]}; + color: ${({ theme }) => theme.colors.neutral[900]}; margin-bottom: 0.5rem; text-align: center; `; -const Subtitle = styled.p` +const Subtitle = styled.p<{ theme: LilithTheme }>` font-size: 1rem; - color: ${(props) => props.theme.colors.neutral[600]}; + color: ${({ theme }) => theme.colors.neutral[600]}; text-align: center; margin-bottom: 2rem; max-width: 480px; @@ -62,45 +63,45 @@ const VibeCheckWrapper = styled.div` overflow: hidden; `; -const AttemptsWarning = styled.div` +const AttemptsWarning = styled.div<{ theme: LilithTheme }>` margin-top: 1rem; padding: 0.75rem 1rem; - background: ${(props) => props.theme.colors.warning[50]}; - border: 1px solid ${(props) => props.theme.colors.warning[300]}; + background: ${({ theme }) => theme.colors.warning[50]}; + border: 1px solid ${({ theme }) => theme.colors.warning[300]}; border-radius: 6px; - color: ${(props) => props.theme.colors.warning[800]}; + color: ${({ theme }) => theme.colors.warning[800]}; font-size: 0.875rem; font-weight: 500; `; -const ErrorMessage = styled.div` +const ErrorMessage = styled.div<{ theme: LilithTheme }>` margin-top: 1rem; padding: 0.75rem 1rem; - background: ${(props) => props.theme.colors.error[50]}; - border: 1px solid ${(props) => props.theme.colors.error[300]}; + background: ${({ theme }) => theme.colors.error[50]}; + border: 1px solid ${({ theme }) => theme.colors.error[300]}; border-radius: 6px; - color: ${(props) => props.theme.colors.error[800]}; + color: ${({ theme }) => theme.colors.error[800]}; font-size: 0.875rem; `; -const SkipButton = styled.button` +const SkipButton = styled.button<{ theme: LilithTheme }>` margin-top: 1.5rem; padding: 0.5rem 1rem; background: transparent; - border: 1px solid ${(props) => props.theme.colors.neutral[300]}; + border: 1px solid ${({ theme }) => theme.colors.neutral[300]}; border-radius: 6px; - color: ${(props) => props.theme.colors.neutral[600]}; + color: ${({ theme }) => theme.colors.neutral[600]}; font-size: 0.875rem; cursor: pointer; transition: all 0.2s; &:hover { - background: ${(props) => props.theme.colors.neutral[50]}; - border-color: ${(props) => props.theme.colors.neutral[400]}; + background: ${({ theme }) => theme.colors.neutral[50]}; + border-color: ${({ theme }) => theme.colors.neutral[400]}; } `; -export const BotDefenseGate: React.FC = ({ +export const BotDefenseGate: FC = ({ onSuccess, onSkip, allowSkip = false, diff --git a/features/bot-defense/frontend-components/src/components/LoadingSpinner.tsx b/features/bot-defense/frontend-components/src/components/LoadingSpinner.tsx index ca919a243..bc5e0ee59 100644 --- a/features/bot-defense/frontend-components/src/components/LoadingSpinner.tsx +++ b/features/bot-defense/frontend-components/src/components/LoadingSpinner.tsx @@ -1,9 +1,10 @@ -/// /** * Simple loading spinner component for bot-defense UI */ +import type { FC } from 'react'; import styled, { keyframes } from '@lilith/ui-styled-components'; +import type { LilithTheme } from '../theme.types'; const spin = keyframes` from { transform: rotate(0deg); } @@ -17,16 +18,16 @@ const SpinnerContainer = styled.div` padding: 2rem; `; -const Spinner = styled.div` +const Spinner = styled.div<{ theme: LilithTheme }>` width: 40px; height: 40px; - border: 4px solid ${(props) => props.theme.colors.neutral[200]}; - border-top-color: ${(props) => props.theme.colors.primary[500]}; + border: 4px solid ${({ theme }) => theme.colors.neutral[200]}; + border-top-color: ${({ theme }) => theme.colors.primary[500]}; border-radius: 50%; animation: ${spin} 1s linear infinite; `; -export const LoadingSpinner: React.FC = () => ( +export const LoadingSpinner: FC = () => ( diff --git a/features/bot-defense/frontend-components/src/index.ts b/features/bot-defense/frontend-components/src/index.ts index 6159f9f00..d20c02db6 100644 --- a/features/bot-defense/frontend-components/src/index.ts +++ b/features/bot-defense/frontend-components/src/index.ts @@ -1,4 +1,3 @@ -/// /** * @lilith/bot-defense-react * Bot defense React components for the Lilith platform diff --git a/features/bot-defense/frontend-components/src/theme.types.ts b/features/bot-defense/frontend-components/src/theme.types.ts new file mode 100644 index 000000000..a4a3c22d3 --- /dev/null +++ b/features/bot-defense/frontend-components/src/theme.types.ts @@ -0,0 +1,13 @@ +/** + * Lilith Platform theme type for bot-defense styled components. + * Mirrors the DefaultTheme augmentation in styled.d.ts. + */ +export interface LilithTheme { + colors: { + primary: Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, string>; + neutral: Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, string>; + error: Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, string>; + warning: Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, string>; + success: Record<50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900, string>; + }; +} diff --git a/features/platform-seed/bin/generate-dev-data.ts b/features/platform-seed/bin/generate-dev-data.ts index de893a531..179711a6f 100644 --- a/features/platform-seed/bin/generate-dev-data.ts +++ b/features/platform-seed/bin/generate-dev-data.ts @@ -18,12 +18,17 @@ import { phase13Streaming } from '../src/phases/phase13-streaming' import { phase14Merchant } from '../src/phases/phase14-merchant' import { phase15Marketplace } from '../src/phases/phase15-marketplace' import { phase16FeatureFlags } from '../src/phases/phase16-feature-flags' +import { phase17Trust } from '../src/phases/phase17-trust' +import { phase18MessagingAgreements } from '../src/phases/phase18-messaging-agreements' +import { phase19MarketplaceRegions } from '../src/phases/phase19-marketplace-regions' +import { phase20MerchantOrders } from '../src/phases/phase20-merchant-orders' import { pullAttrs } from '../src/sync/pull-attrs' import { pushAttrs } from '../src/sync/push-attrs' import { diffAttrs } from '../src/sync/diff-attrs' import { withDb, ANALYTICS_DB, SSO_DB, MESSAGING_DB, REVIEWS_DB, PAYMENTS_DB, STREAMING_DB, MERCHANT_DB, MARKETPLACE_DB, FEATURE_FLAGS_DB, + TRUST_DB, } from '../src/lib/db' import type { UserRecord } from '../src/phases/phase1-sso-users' import type { ProfileRecord } from '../src/phases/phase3-profiles' @@ -55,12 +60,17 @@ const PHASE_DEPS: Record = { '6': ['1', '1b'], '12': ['1', '1b'], '13': ['1'], '14': ['1', '1b'], '15': ['1b'], '7': ['1', '3'], + '17': ['1', '1b'], // trust proofs — needs both user sets + '18': ['1', '1b', '9'], // messaging agreements — needs threads from phase 9 + '19': [], // marketplace regions — standalone + '20': ['1b', '14'], // merchant orders — needs client users + products from phase 14 } const ALL_PHASE_ORDER = [ '1', '1b', '1c', '2', '3', '4', '5', '8', '9', '10', '11', '6', '12', '13', '14', '15', '7', '16', + '17', '18', '19', '20', ] function printUsage(): void { @@ -103,6 +113,12 @@ Phases: 7 Cost entries & metrics (direct DB) 16 Feature flags (direct DB) + TIER 4 — Trust & Commerce: + 17 Trust verification proofs (direct DB) + 18 Messaging agreements (direct DB) + 19 Marketplace regions (direct DB) + 20 Merchant orders + order items (direct DB) + Sync Modes: pull DB → filesystem push filesystem → DB @@ -147,8 +163,9 @@ async function runStatus(): Promise { { name: 'Payments', config: PAYMENTS_DB, tables: ['payment_methods', 'subscriptions', 'transactions'] }, { name: 'Streaming', config: STREAMING_DB, tables: ['stream_sessions', 'stream_tips'] }, { name: 'Merchant', config: MERCHANT_DB, tables: ['provider_stores', 'merchant_products'] }, - { name: 'Marketplace', config: MARKETPLACE_DB, tables: ['marketplace_platform_subscription_tiers', 'marketplace_platform_subscriptions'] }, + { name: 'Marketplace', config: MARKETPLACE_DB, tables: ['marketplace_platform_subscription_tiers', 'marketplace_platform_subscriptions', 'marketplace_regions'] }, { name: 'FeatureFlags', config: FEATURE_FLAGS_DB, tables: ['feature_flags'] }, + { name: 'Trust', config: TRUST_DB, tables: ['verification_proofs'] }, ] for (const check of dbChecks) { @@ -180,8 +197,10 @@ async function runReset(): Promise { { name: 'Payments', config: PAYMENTS_DB, tables: ['transactions', 'subscriptions', 'payment_methods'] }, { name: 'Streaming', config: STREAMING_DB, tables: ['stream_tips', 'stream_sessions'] }, { name: 'Merchant', config: MERCHANT_DB, tables: ['merchant_products', 'provider_stores'] }, - { name: 'Marketplace', config: MARKETPLACE_DB, tables: ['marketplace_platform_subscriptions', 'marketplace_platform_subscription_tiers'] }, + { name: 'Marketplace', config: MARKETPLACE_DB, tables: ['marketplace_platform_subscriptions', 'marketplace_platform_subscription_tiers', 'marketplace_regions'] }, { name: 'FeatureFlags', config: FEATURE_FLAGS_DB, tables: ['feature_flags'] }, + { name: 'Trust', config: TRUST_DB, tables: ['verification_proofs'] }, + { name: 'Merchant (orders)', config: MERCHANT_DB, tables: ['merchant_order_items', 'merchant_orders'] }, ] for (const reset of dbResets) { @@ -304,6 +323,18 @@ async function runPhase(phase: string, ctx: SeedContext): Promise { case '16': await phase16FeatureFlags() break + case '17': + await phase17Trust(ctx.providerUsers, ctx.clientUsers) + break + case '18': + await phase18MessagingAgreements(ctx.providerUsers, ctx.clientUsers) + break + case '19': + await phase19MarketplaceRegions() + break + case '20': + await phase20MerchantOrders(ctx.clientUsers) + break default: logError(`Unknown phase: ${phase}. Use --help for available phases.`) process.exit(1) @@ -344,7 +375,7 @@ async function main(): Promise { if (values.all) { log('╔═══════════════════════════════════════════╗') log('║ Lilith Platform Dev Data Generator ║') - log('║ Running all 18 phases... ║') + log('║ Running all 22 phases... ║') log('╚═══════════════════════════════════════════╝') let ctx: SeedContext = { diff --git a/features/video-studio/packages/media-gallery/app.manifest.yaml b/features/video-studio/packages/media-gallery/app.manifest.yaml index 8fb8a9a1a..421507896 100644 --- a/features/video-studio/packages/media-gallery/app.manifest.yaml +++ b/features/video-studio/packages/media-gallery/app.manifest.yaml @@ -18,7 +18,6 @@ platforms: type: web port: "5220" description: LilithPhotos gallery UI - supporting-services: media-gallery-postgres: type: docker port: "25448"