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"