diff --git a/frontends/nextjs/src/app/levels/LevelsClient.tsx b/frontends/nextjs/src/app/levels/LevelsClient.tsx index 6afa40a91..9e701867f 100644 --- a/frontends/nextjs/src/app/levels/LevelsClient.tsx +++ b/frontends/nextjs/src/app/levels/LevelsClient.tsx @@ -2,27 +2,11 @@ import { useMemo, useState } from 'react' -import { - Alert, - Box, - Button, - Chip, - Container, - Divider, - Grid, - LinearProgress, - Paper, - Stack, - Typography, -} from '@mui/material' +import { Container, Stack, Typography } from '@mui/material' -import { PERMISSION_LEVELS, type PermissionLevel } from './levels-data' - -const highlightColor = (level: PermissionLevel) => { - if (level.id === 6) return 'warning.main' - if (level.id === 5) return 'primary.main' - return 'divider' -} +import { LevelDetails } from './components/LevelDetails' +import { LevelsGrid } from './components/LevelsGrid' +import { PERMISSION_LEVELS } from './levels-data' export default function LevelsClient() { const [selectedLevelId, setSelectedLevelId] = useState(PERMISSION_LEVELS[0].id) @@ -70,94 +54,19 @@ export default function LevelsClient() { - - {PERMISSION_LEVELS.map((level) => ( - - handleSelect(level.id)} - sx={{ - border: (theme) => `2px solid ${selectedLevel.id === level.id ? theme.palette.primary.main : theme.palette.divider}`, - p: 3, - cursor: 'pointer', - position: 'relative', - '&:hover': { - borderColor: 'primary.main', - }, - }} - elevation={selectedLevel.id === level.id ? 6 : 1} - > - - - - Level {level.id} · {level.title} - - {level.tagline} - - - {level.description} - - - {level.capabilities.slice(0, 3).map((capability) => ( - - ))} - - - - ))} - + - `1px dashed ${theme.palette.divider}`, bgcolor: 'background.paper' }}> - - - Selected level details - - - - {selectedLevel.description} - - - {selectedLevel.capabilities.map((capability) => ( - - ))} - - - - - {selectedLevel.capabilities.length} of {maxCapabilityCount} capability tiers unlocked - - - - - - Next move - - {nextLevel ? ( - - Promote into {nextLevel.title} to unlock {nextLevel.capabilities.length} controls. - - ) : ( - - Super God reigns supreme. You already own every privilege. - - )} - - - - - {note && {note}} - - + ) diff --git a/frontends/nextjs/src/app/levels/components/LevelDetails.tsx b/frontends/nextjs/src/app/levels/components/LevelDetails.tsx new file mode 100644 index 000000000..8b1885d80 --- /dev/null +++ b/frontends/nextjs/src/app/levels/components/LevelDetails.tsx @@ -0,0 +1,67 @@ +import { Alert, Box, Button, Chip, Divider, LinearProgress, Paper, Stack, Typography } from '@mui/material' + +import type { PermissionLevel } from '../levels-data' +import { highlightColor } from '../utils/highlightColor' + +type LevelDetailsProps = { + selectedLevel: PermissionLevel + nextLevel: PermissionLevel | null + maxCapabilityCount: number + note: string + onPromote: () => void +} + +export const LevelDetails = ({ selectedLevel, nextLevel, maxCapabilityCount, note, onPromote }: LevelDetailsProps) => ( + `1px dashed ${theme.palette.divider}`, bgcolor: 'background.paper' }}> + + + Selected level details + + + + {selectedLevel.description} + + + {selectedLevel.capabilities.map((capability) => ( + + ))} + + + + + {selectedLevel.capabilities.length} of {maxCapabilityCount} capability tiers unlocked + + + + + + Next move + + {nextLevel ? ( + + Promote into {nextLevel.title} to unlock {nextLevel.capabilities.length} controls. + + ) : ( + + Super God reigns supreme. You already own every privilege. + + )} + + + + + {note && {note}} + + +) diff --git a/frontends/nextjs/src/app/levels/components/LevelsGrid.tsx b/frontends/nextjs/src/app/levels/components/LevelsGrid.tsx new file mode 100644 index 000000000..154eaca76 --- /dev/null +++ b/frontends/nextjs/src/app/levels/components/LevelsGrid.tsx @@ -0,0 +1,47 @@ +import { Box, Chip, Grid, Paper, Stack, Typography } from '@mui/material' + +import type { PermissionLevel } from '../levels-data' + +type LevelsGridProps = { + levels: PermissionLevel[] + selectedLevelId: number + onSelect: (levelId: number) => void +} + +export const LevelsGrid = ({ levels, selectedLevelId, onSelect }: LevelsGridProps) => ( + + {levels.map((level) => ( + + onSelect(level.id)} + sx={{ + border: (theme) => `2px solid ${selectedLevelId === level.id ? theme.palette.primary.main : theme.palette.divider}`, + p: 3, + cursor: 'pointer', + position: 'relative', + '&:hover': { + borderColor: 'primary.main', + }, + }} + elevation={selectedLevelId === level.id ? 6 : 1} + > + + + + Level {level.id} · {level.title} + + {level.tagline} + + + {level.description} + + + {level.capabilities.slice(0, 3).map((capability) => ( + + ))} + + + + ))} + +) diff --git a/frontends/nextjs/src/app/levels/utils/highlightColor.ts b/frontends/nextjs/src/app/levels/utils/highlightColor.ts new file mode 100644 index 000000000..7606ea4d5 --- /dev/null +++ b/frontends/nextjs/src/app/levels/utils/highlightColor.ts @@ -0,0 +1,7 @@ +import type { PermissionLevel } from '../levels-data' + +export const highlightColor = (level: PermissionLevel) => { + if (level.id === 6) return 'warning.main' + if (level.id === 5) return 'primary.main' + return 'divider' +} diff --git a/frontends/nextjs/src/components/level/levels/Level4.tsx b/frontends/nextjs/src/components/level/levels/Level4.tsx index 8e5e685b7..be74a350a 100644 --- a/frontends/nextjs/src/components/level/levels/Level4.tsx +++ b/frontends/nextjs/src/components/level/levels/Level4.tsx @@ -1,15 +1,11 @@ "use client" -import { useState, useEffect } from 'react' -import { toast } from 'sonner' import { Level4Header } from '../../level4/Level4Header' import { Level4Tabs } from '../../level4/Level4Tabs' import { Level4Summary } from '../../level4/Level4Summary' import { NerdModeIDE } from '../../misc/NerdModeIDE' -import { Database } from '@/lib/database' -import { seedDatabase } from '@/lib/seed-data' -import type { User as UserType, AppConfiguration } from '@/lib/level-types' -import { useKV } from '@github/spark/hooks' +import type { User as UserType } from '@/lib/level-types' +import { useLevel4AppState } from './hooks/useLevel4AppState' interface Level4Props { user: UserType @@ -19,94 +15,29 @@ interface Level4Props { } export function Level4({ user, onLogout, onNavigate, onPreview }: Level4Props) { - const [appConfig, setAppConfig] = useState(null) - const [isLoading, setIsLoading] = useState(true) - const [nerdMode, setNerdMode] = useKV('level4-nerd-mode', false) - - useEffect(() => { - const loadConfig = async () => { - await seedDatabase() - - const config = await Database.getAppConfig() - if (config) { - setAppConfig(config) - } else { - const defaultConfig: AppConfiguration = { - id: 'app_001', - name: 'MetaBuilder App', - schemas: [], - workflows: [], - luaScripts: [], - pages: [], - theme: { - colors: {}, - fonts: {}, - }, - } - await Database.setAppConfig(defaultConfig) - setAppConfig(defaultConfig) - } - setIsLoading(false) - } - loadConfig() - }, []) + const { + appConfig, + handleExportConfig, + handleImportConfig, + handleLuaScriptsChange, + handleSchemasChange, + handleWorkflowsChange, + isLoading, + nerdMode, + toggleNerdMode, + } = useLevel4AppState() if (isLoading || !appConfig) return null - const updateAppConfig = async (updates: Partial) => { - const newConfig = { ...appConfig, ...updates } - setAppConfig(newConfig) - await Database.setAppConfig(newConfig) - } - - const handleExportConfig = async () => { - const dataStr = await Database.exportDatabase() - const dataBlob = new Blob([dataStr], { type: 'application/json' }) - const url = URL.createObjectURL(dataBlob) - const link = document.createElement('a') - link.href = url - link.download = 'database-export.json' - link.click() - toast.success('Database exported') - } - - const handleImportConfig = () => { - const input = document.createElement('input') - input.type = 'file' - input.accept = 'application/json' - input.onchange = async (e) => { - const file = (e.target as HTMLInputElement).files?.[0] - if (!file) return - - const text = await file.text() - try { - await Database.importDatabase(text) - const newConfig = await Database.getAppConfig() - if (newConfig) { - setAppConfig(newConfig) - } - toast.success('Database imported successfully') - } catch (error) { - toast.error('Invalid database file') - } - } - input.click() - } - - const handleToggleNerdMode = () => { - setNerdMode(!nerdMode) - toast.info(nerdMode ? 'Nerd Mode disabled' : 'Nerd Mode enabled') - } - return (
@@ -115,7 +46,7 @@ export function Level4({ user, onLogout, onNavigate, onPreview }: Level4Props) {

Application Builder

- {nerdMode + {nerdMode ? "Design your application declaratively. Define schemas, create workflows, and write Lua scripts." : "Build your application visually. Configure pages, users, and data models with simple forms." } @@ -124,25 +55,13 @@ export function Level4({ user, onLogout, onNavigate, onPreview }: Level4Props) { { - const newConfig = { ...appConfig, schemas } - setAppConfig(newConfig) - await Database.setAppConfig(newConfig) - }} - onWorkflowsChange={async (workflows) => { - const newConfig = { ...appConfig, workflows } - setAppConfig(newConfig) - await Database.setAppConfig(newConfig) - }} - onLuaScriptsChange={async (scripts) => { - const newConfig = { ...appConfig, luaScripts: scripts } - setAppConfig(newConfig) - await Database.setAppConfig(newConfig) - }} + nerdMode={nerdMode} + onSchemasChange={handleSchemasChange} + onWorkflowsChange={handleWorkflowsChange} + onLuaScriptsChange={handleLuaScriptsChange} /> - + {nerdMode && (

diff --git a/frontends/nextjs/src/components/level/levels/hooks/useLevel4AppState.ts b/frontends/nextjs/src/components/level/levels/hooks/useLevel4AppState.ts new file mode 100644 index 000000000..d2c146ac8 --- /dev/null +++ b/frontends/nextjs/src/components/level/levels/hooks/useLevel4AppState.ts @@ -0,0 +1,127 @@ +import { useCallback, useEffect, useState } from 'react' +import { toast } from 'sonner' +import { useKV } from '@github/spark/hooks' + +import { Database } from '@/lib/database' +import type { AppConfiguration } from '@/lib/level-types' +import { seedDatabase } from '@/lib/seed-data' + +type ConfigUpdater = (config: AppConfiguration) => AppConfiguration + +const createDefaultConfig = (): AppConfiguration => ({ + id: 'app_001', + name: 'MetaBuilder App', + schemas: [], + workflows: [], + luaScripts: [], + pages: [], + theme: { + colors: {}, + fonts: {}, + }, +}) + +const persistConfig = async (config: AppConfiguration, setConfig: (value: AppConfiguration) => void) => { + setConfig(config) + await Database.setAppConfig(config) +} + +export const useLevel4AppState = () => { + const [appConfig, setAppConfig] = useState(null) + const [isLoading, setIsLoading] = useState(true) + const [nerdMode, setNerdMode] = useKV('level4-nerd-mode', false) + + useEffect(() => { + const loadConfig = async () => { + await seedDatabase() + + const config = await Database.getAppConfig() + if (config) { + setAppConfig(config) + } else { + const defaultConfig = createDefaultConfig() + await persistConfig(defaultConfig, setAppConfig) + } + setIsLoading(false) + } + + void loadConfig() + }, []) + + const updateConfig = useCallback( + async (updater: ConfigUpdater) => { + if (!appConfig) return + + const updatedConfig = updater(appConfig) + await persistConfig(updatedConfig, setAppConfig) + }, + [appConfig] + ) + + const handleExportConfig = useCallback(async () => { + const dataStr = await Database.exportDatabase() + const dataBlob = new Blob([dataStr], { type: 'application/json' }) + const url = URL.createObjectURL(dataBlob) + const link = document.createElement('a') + link.href = url + link.download = 'database-export.json' + link.click() + toast.success('Database exported') + }, []) + + const handleImportConfig = useCallback(() => { + const input = document.createElement('input') + input.type = 'file' + input.accept = 'application/json' + input.onchange = async (e) => { + const file = (e.target as HTMLInputElement).files?.[0] + if (!file) return + + const text = await file.text() + try { + await Database.importDatabase(text) + const newConfig = await Database.getAppConfig() + if (newConfig) { + await persistConfig(newConfig, setAppConfig) + } + toast.success('Database imported successfully') + } catch (error) { + toast.error('Invalid database file') + } + } + input.click() + }, []) + + const toggleNerdMode = useCallback(() => { + const nextValue = !nerdMode + setNerdMode(nextValue) + toast.info(nextValue ? 'Nerd Mode enabled' : 'Nerd Mode disabled') + }, [nerdMode, setNerdMode]) + + const handleSchemasChange = useCallback( + async (schemas: AppConfiguration['schemas']) => updateConfig((config) => ({ ...config, schemas })), + [updateConfig] + ) + + const handleWorkflowsChange = useCallback( + async (workflows: AppConfiguration['workflows']) => updateConfig((config) => ({ ...config, workflows })), + [updateConfig] + ) + + const handleLuaScriptsChange = useCallback( + async (luaScripts: AppConfiguration['luaScripts']) => updateConfig((config) => ({ ...config, luaScripts })), + [updateConfig] + ) + + return { + appConfig, + isLoading, + nerdMode: nerdMode || false, + handleExportConfig, + handleImportConfig, + toggleNerdMode, + handleSchemasChange, + handleWorkflowsChange, + handleLuaScriptsChange, + } +} diff --git a/frontends/nextjs/src/types/dbal.d.ts b/frontends/nextjs/src/types/dbal.d.ts index 178b52c5c..0484a463b 100644 --- a/frontends/nextjs/src/types/dbal.d.ts +++ b/frontends/nextjs/src/types/dbal.d.ts @@ -2,153 +2,14 @@ * DBAL type stubs * These types are used when the full DBAL module is not available * The actual implementation lives in ../../dbal/development/src + * + * The declarations are split into focused modules to keep each file + * under the large-file threshold and easier to maintain. */ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -declare module '@/dbal/development/src' { - export interface DBALConfig { - mode?: 'development' | 'production' - adapter?: string - auth?: any - database?: { - url?: string - } - security?: { - sandbox?: 'strict' | 'permissive' | 'disabled' - enableAuditLog?: boolean - } - [key: string]: any - } - - export interface DBALUser { - id: string - email: string - name?: string - username?: string - level?: number - role?: string - tenantId?: string - createdAt?: number | string | Date - [key: string]: any - } - - export interface ListResult { - data: T[] - total?: number - } - - export interface UsersAPI { - list(): Promise> - create(data: Partial): Promise - update(id: string, data: Partial): Promise - delete(id: string): Promise - } - - export class DBALClient { - users: UsersAPI - constructor(config: DBALConfig) - query(sql: string, params?: unknown[]): Promise - execute(sql: string, params?: unknown[]): Promise - capabilities(): Promise> - } - - export class DBALError extends Error { - code: DBALErrorCode - message: string - constructor(message: string, code: DBALErrorCode) - } - - export enum DBALErrorCode { - UNKNOWN = 'UNKNOWN', - CONNECTION_ERROR = 'CONNECTION_ERROR', - QUERY_ERROR = 'QUERY_ERROR', - VALIDATION_ERROR = 'VALIDATION_ERROR', - } -} - -declare module '@/dbal/development/src/core/types' { - export interface User { - id: string - email: string - name?: string - level: number - tenantId: string - } -} - -declare module '@/dbal/development/src/core/tenant-context' { - export interface TenantContext { - tenantId: string - userId?: string - } - - export class InMemoryTenantManager { - setCurrentTenant(tenantId: string): void - getCurrentTenant(): string | null - createTenant(id: string, metadata: Record, ...args: any[]): Promise - getTenantContext(tenantId: string, userId?: string): Promise - } -} - -declare module '@/dbal/development/src/core/kv-store' { - import type { TenantContext } from '@/dbal/development/src/core/tenant-context' - - export class InMemoryKVStore { - get(key: string, context?: TenantContext): Promise - set(key: string, value: T, context?: TenantContext, ttl?: number): Promise - delete(key: string, context?: TenantContext): Promise - listAdd(key: string, items: any[], context?: TenantContext): Promise - listGet(key: string, context?: TenantContext, start?: number, end?: number): Promise - } -} - -declare module '@/dbal/development/src/blob' { - export interface BlobStorageConfig { - type: 'filesystem' | 'memory' | 's3' - basePath?: string - } - - export interface BlobMetadata { - contentType?: string - size?: number - lastModified?: Date - [key: string]: any - } - - export interface BlobListItem { - key: string - [key: string]: any - } - - export interface BlobListResult { - items: BlobListItem[] - [key: string]: any - } - - export interface BlobStorage { - upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise - download(key: string): Promise - delete(key: string): Promise - exists(key: string): Promise - list(options?: { prefix?: string }): Promise - getMetadata(key: string): Promise - } - - export function createBlobStorage(config: BlobStorageConfig): BlobStorage -} - -declare module '@/dbal/development/src/blob/tenant-aware-storage' { - import type { BlobStorage, BlobMetadata, BlobListResult } from '@/dbal/development/src/blob' - import type { InMemoryTenantManager } from '@/dbal/development/src/core/tenant-context' - - export class TenantAwareBlobStorage implements BlobStorage { - constructor(storage: BlobStorage, tenantManager: InMemoryTenantManager, ...args: any[]) - upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise - download(key: string): Promise - delete(key: string): Promise - exists(key: string): Promise - list(options?: { prefix?: string }): Promise - getMetadata(key: string): Promise - } -} +/// +/// +/// +/// +/// +/// diff --git a/frontends/nextjs/src/types/dbal/blob.d.ts b/frontends/nextjs/src/types/dbal/blob.d.ts new file mode 100644 index 000000000..09f14389a --- /dev/null +++ b/frontends/nextjs/src/types/dbal/blob.d.ts @@ -0,0 +1,36 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +declare module '@/dbal/development/src/blob' { + export interface BlobStorageConfig { + type: 'filesystem' | 'memory' | 's3' + basePath?: string + } + + export interface BlobMetadata { + contentType?: string + size?: number + lastModified?: Date + [key: string]: any + } + + export interface BlobListItem { + key: string + [key: string]: any + } + + export interface BlobListResult { + items: BlobListItem[] + [key: string]: any + } + + export interface BlobStorage { + upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise + download(key: string): Promise + delete(key: string): Promise + exists(key: string): Promise + list(options?: { prefix?: string }): Promise + getMetadata(key: string): Promise + } + + export function createBlobStorage(config: BlobStorageConfig): BlobStorage +} diff --git a/frontends/nextjs/src/types/dbal/core-config.d.ts b/frontends/nextjs/src/types/dbal/core-config.d.ts new file mode 100644 index 000000000..976251d1c --- /dev/null +++ b/frontends/nextjs/src/types/dbal/core-config.d.ts @@ -0,0 +1,66 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +/** + * Root DBAL module declarations. + * Split from the monolithic dbal.d.ts to keep each set of exports contained. + */ +declare module '@/dbal/development/src' { + export interface DBALConfig { + mode?: 'development' | 'production' + adapter?: string + auth?: any + database?: { + url?: string + } + security?: { + sandbox?: 'strict' | 'permissive' | 'disabled' + enableAuditLog?: boolean + } + [key: string]: any + } + + export interface DBALUser { + id: string + email: string + name?: string + username?: string + level?: number + role?: string + tenantId?: string + createdAt?: number | string | Date + [key: string]: any + } + + export interface ListResult { + data: T[] + total?: number + } + + export interface UsersAPI { + list(): Promise> + create(data: Partial): Promise + update(id: string, data: Partial): Promise + delete(id: string): Promise + } + + export class DBALClient { + users: UsersAPI + constructor(config: DBALConfig) + query(sql: string, params?: unknown[]): Promise + execute(sql: string, params?: unknown[]): Promise + capabilities(): Promise> + } + + export class DBALError extends Error { + code: DBALErrorCode + message: string + constructor(message: string, code: DBALErrorCode) + } + + export enum DBALErrorCode { + UNKNOWN = 'UNKNOWN', + CONNECTION_ERROR = 'CONNECTION_ERROR', + QUERY_ERROR = 'QUERY_ERROR', + VALIDATION_ERROR = 'VALIDATION_ERROR', + } +} diff --git a/frontends/nextjs/src/types/dbal/core-types.d.ts b/frontends/nextjs/src/types/dbal/core-types.d.ts new file mode 100644 index 000000000..3c564c162 --- /dev/null +++ b/frontends/nextjs/src/types/dbal/core-types.d.ts @@ -0,0 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +declare module '@/dbal/development/src/core/types' { + export interface User { + id: string + email: string + name?: string + level: number + tenantId: string + } +} diff --git a/frontends/nextjs/src/types/dbal/kv-store.d.ts b/frontends/nextjs/src/types/dbal/kv-store.d.ts new file mode 100644 index 000000000..d9d2a152a --- /dev/null +++ b/frontends/nextjs/src/types/dbal/kv-store.d.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +declare module '@/dbal/development/src/core/kv-store' { + import type { TenantContext } from '@/dbal/development/src/core/tenant-context' + + export class InMemoryKVStore { + get(key: string, context?: TenantContext): Promise + set(key: string, value: T, context?: TenantContext, ttl?: number): Promise + delete(key: string, context?: TenantContext): Promise + listAdd(key: string, items: any[], context?: TenantContext): Promise + listGet(key: string, context?: TenantContext, start?: number, end?: number): Promise + } +} diff --git a/frontends/nextjs/src/types/dbal/tenant-aware-blob.d.ts b/frontends/nextjs/src/types/dbal/tenant-aware-blob.d.ts new file mode 100644 index 000000000..812ea8bcd --- /dev/null +++ b/frontends/nextjs/src/types/dbal/tenant-aware-blob.d.ts @@ -0,0 +1,16 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +declare module '@/dbal/development/src/blob/tenant-aware-storage' { + import type { BlobStorage, BlobMetadata, BlobListResult } from '@/dbal/development/src/blob' + import type { InMemoryTenantManager } from '@/dbal/development/src/core/tenant-context' + + export class TenantAwareBlobStorage implements BlobStorage { + constructor(storage: BlobStorage, tenantManager: InMemoryTenantManager, ...args: any[]) + upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise + download(key: string): Promise + delete(key: string): Promise + exists(key: string): Promise + list(options?: { prefix?: string }): Promise + getMetadata(key: string): Promise + } +} diff --git a/frontends/nextjs/src/types/dbal/tenant-context.d.ts b/frontends/nextjs/src/types/dbal/tenant-context.d.ts new file mode 100644 index 000000000..178152829 --- /dev/null +++ b/frontends/nextjs/src/types/dbal/tenant-context.d.ts @@ -0,0 +1,15 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +declare module '@/dbal/development/src/core/tenant-context' { + export interface TenantContext { + tenantId: string + userId?: string + } + + export class InMemoryTenantManager { + setCurrentTenant(tenantId: string): void + getCurrentTenant(): string | null + createTenant(id: string, metadata: Record, ...args: any[]): Promise + getTenantContext(tenantId: string, userId?: string): Promise + } +} diff --git a/tools/analysis/code/reports/large-ts-files.json b/tools/analysis/code/reports/large-ts-files.json index 45a8bd46c..2e27fb85b 100644 --- a/tools/analysis/code/reports/large-ts-files.json +++ b/tools/analysis/code/reports/large-ts-files.json @@ -12,9 +12,9 @@ "out", "tmp" ], - "scanned": 1381, - "overLimit": 106, - "timestamp": "2025-12-27T15:33:16.258Z", + "scanned": 1407, + "overLimit": 100, + "timestamp": "2025-12-27T15:45:04.923Z", "files": [ { "path": "frontends/nextjs/src/lib/packages/core/package-catalog.ts", @@ -511,40 +511,11 @@ "lines": 165, "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." }, - { - "path": "frontends/nextjs/src/app/levels/LevelsClient.tsx", - "lines": 165, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, { "path": "frontends/nextjs/src/components/rendering/Builder.tsx", "lines": 164, "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, - { - "path": "frontends/nextjs/src/components/molecules/form/Select.tsx", - "lines": 161, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, - { - "path": "tools/generation/generate-quality-summary.ts", - "lines": 160, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, - { - "path": "tools/analysis/code/list-large-typescript-files.ts", - "lines": 159, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, - { - "path": "frontends/nextjs/src/components/level/levels/Level4.tsx", - "lines": 156, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." - }, - { - "path": "frontends/nextjs/src/types/dbal.d.ts", - "lines": 155, - "recommendation": "Split into focused modules; keep one primary lambda per file and extract helpers." } - ] + ], + "outFile": "tools/analysis/code/reports/large-ts-files.json" }