diff --git a/dbal/ts/src/adapters/adapter.ts b/dbal/ts/src/adapters/adapter.ts index 669236d45..3ed0ad651 100644 --- a/dbal/ts/src/adapters/adapter.ts +++ b/dbal/ts/src/adapters/adapter.ts @@ -11,12 +11,24 @@ export interface AdapterCapabilities { } export interface DBALAdapter { + // Core CRUD operations create(entity: string, data: Record): Promise read(entity: string, id: string): Promise update(entity: string, id: string, data: Record): Promise delete(entity: string, id: string): Promise list(entity: string, options?: ListOptions): Promise> + // Extended query operations + findFirst(entity: string, filter?: Record): Promise + findByField(entity: string, field: string, value: unknown): Promise + + // Extended mutation operations + upsert(entity: string, uniqueField: string, uniqueValue: unknown, createData: Record, updateData: Record): Promise + updateByField(entity: string, field: string, value: unknown, data: Record): Promise + deleteByField(entity: string, field: string, value: unknown): Promise + deleteMany(entity: string, filter?: Record): Promise + createMany(entity: string, data: Record[]): Promise + getCapabilities(): Promise close(): Promise } diff --git a/dbal/ts/src/adapters/prisma-adapter.ts b/dbal/ts/src/adapters/prisma-adapter.ts index ef9b447cc..93c50d634 100644 --- a/dbal/ts/src/adapters/prisma-adapter.ts +++ b/dbal/ts/src/adapters/prisma-adapter.ts @@ -106,6 +106,108 @@ export class PrismaAdapter implements DBALAdapter { } } + async findFirst(entity: string, filter?: Record): Promise { + try { + const model = this.getModel(entity) + const where = filter ? this.buildWhereClause(filter) : undefined + const result = await this.withTimeout( + model.findFirst({ where: where as never }) + ) + return result + } catch (error) { + throw this.handleError(error, 'findFirst', entity) + } + } + + async findByField(entity: string, field: string, value: unknown): Promise { + try { + const model = this.getModel(entity) + const result = await this.withTimeout( + model.findUnique({ where: { [field]: value } as never }) + ) + return result + } catch (error) { + throw this.handleError(error, 'findByField', entity) + } + } + + async upsert( + entity: string, + uniqueField: string, + uniqueValue: unknown, + createData: Record, + updateData: Record + ): Promise { + try { + const model = this.getModel(entity) + const result = await this.withTimeout( + model.upsert({ + where: { [uniqueField]: uniqueValue } as never, + create: createData as never, + update: updateData as never, + }) + ) + return result + } catch (error) { + throw this.handleError(error, 'upsert', entity) + } + } + + async updateByField(entity: string, field: string, value: unknown, data: Record): Promise { + try { + const model = this.getModel(entity) + const result = await this.withTimeout( + model.update({ + where: { [field]: value } as never, + data: data as never, + }) + ) + return result + } catch (error) { + throw this.handleError(error, 'updateByField', entity) + } + } + + async deleteByField(entity: string, field: string, value: unknown): Promise { + try { + const model = this.getModel(entity) + await this.withTimeout( + model.delete({ where: { [field]: value } as never }) + ) + return true + } catch (error) { + if (this.isNotFoundError(error)) { + return false + } + throw this.handleError(error, 'deleteByField', entity) + } + } + + async deleteMany(entity: string, filter?: Record): Promise { + try { + const model = this.getModel(entity) + const where = filter ? this.buildWhereClause(filter) : undefined + const result = await this.withTimeout( + model.deleteMany({ where: where as never }) + ) + return result.count + } catch (error) { + throw this.handleError(error, 'deleteMany', entity) + } + } + + async createMany(entity: string, data: Record[]): Promise { + try { + const model = this.getModel(entity) + const result = await this.withTimeout( + model.createMany({ data: data as never }) + ) + return result.count + } catch (error) { + throw this.handleError(error, 'createMany', entity) + } + } + async getCapabilities(): Promise { return { transactions: true, diff --git a/frontends/nextjs/src/App.tsx b/frontends/nextjs/src/_legacy/App.tsx similarity index 100% rename from frontends/nextjs/src/App.tsx rename to frontends/nextjs/src/_legacy/App.tsx diff --git a/frontends/nextjs/src/ErrorFallback.tsx b/frontends/nextjs/src/_legacy/ErrorFallback.tsx similarity index 100% rename from frontends/nextjs/src/ErrorFallback.tsx rename to frontends/nextjs/src/_legacy/ErrorFallback.tsx diff --git a/frontends/nextjs/src/index.scss b/frontends/nextjs/src/_legacy/index.scss similarity index 100% rename from frontends/nextjs/src/index.scss rename to frontends/nextjs/src/_legacy/index.scss diff --git a/frontends/nextjs/src/main.tsx b/frontends/nextjs/src/_legacy/main.tsx similarity index 100% rename from frontends/nextjs/src/main.tsx rename to frontends/nextjs/src/_legacy/main.tsx diff --git a/frontends/nextjs/src/vite-end.d.ts b/frontends/nextjs/src/_legacy/vite-end.d.ts similarity index 100% rename from frontends/nextjs/src/vite-end.d.ts rename to frontends/nextjs/src/_legacy/vite-end.d.ts diff --git a/frontends/nextjs/src/components/ui/atoms/Textarea.tsx b/frontends/nextjs/src/components/ui/atoms/Textarea.tsx index 94923b16b..b6572c698 100644 --- a/frontends/nextjs/src/components/ui/atoms/Textarea.tsx +++ b/frontends/nextjs/src/components/ui/atoms/Textarea.tsx @@ -1,19 +1,35 @@ 'use client' -import { forwardRef, TextareaHTMLAttributes } from 'react' -import { InputBase } from '@mui/material' +import { forwardRef } from 'react' +import { InputBase, InputBaseProps } from '@mui/material' -export interface TextareaProps extends Omit, 'style'> { +export interface TextareaProps { error?: boolean + disabled?: boolean + placeholder?: string + value?: string + defaultValue?: string + onChange?: (event: React.ChangeEvent) => void + onBlur?: (event: React.FocusEvent) => void + onFocus?: (event: React.FocusEvent) => void + name?: string + id?: string + rows?: number + minRows?: number + maxRows?: number + className?: string + required?: boolean + readOnly?: boolean + autoFocus?: boolean } const Textarea = forwardRef( - ({ error, ...props }, ref) => { + ({ error, minRows = 3, ...props }, ref) => { return ( ( ({ children, ...props }, ref) => { return ( } + ref={ref as unknown as React.Ref} expandIcon={} sx={{ '& .MuiAccordionSummary-content': { diff --git a/frontends/nextjs/src/components/ui/molecules/Dialog.tsx b/frontends/nextjs/src/components/ui/molecules/Dialog.tsx index ed83bc721..b1ba9106a 100644 --- a/frontends/nextjs/src/components/ui/molecules/Dialog.tsx +++ b/frontends/nextjs/src/components/ui/molecules/Dialog.tsx @@ -67,7 +67,7 @@ const DialogClose = forwardRef( ({ children, onClick, ...props }, ref) => { if (children) { return ( - } onClick={onClick} sx={{ display: 'inline-flex' }} {...props}> + } onClick={onClick} sx={{ display: 'inline-flex' }} {...props}> {children} ) diff --git a/frontends/nextjs/src/components/ui/molecules/DropdownMenu.tsx b/frontends/nextjs/src/components/ui/molecules/DropdownMenu.tsx index 22e134f33..fa13bc4ea 100644 --- a/frontends/nextjs/src/components/ui/molecules/DropdownMenu.tsx +++ b/frontends/nextjs/src/components/ui/molecules/DropdownMenu.tsx @@ -21,7 +21,7 @@ interface DropdownMenuTriggerProps { const DropdownMenuTrigger = forwardRef( ({ children, asChild, ...props }, ref) => { return ( - } sx={{ display: 'inline-flex' }} {...props}> + } sx={{ display: 'inline-flex' }} {...props}> {children} ) diff --git a/frontends/nextjs/src/components/ui/molecules/Tooltip.tsx b/frontends/nextjs/src/components/ui/molecules/Tooltip.tsx index ee9bc166e..bfd88b34d 100644 --- a/frontends/nextjs/src/components/ui/molecules/Tooltip.tsx +++ b/frontends/nextjs/src/components/ui/molecules/Tooltip.tsx @@ -44,10 +44,10 @@ interface TooltipContentProps { } const TooltipContent = forwardRef( - ({ children, side = 'top', sideOffset = 4, ...props }, ref) => { + ({ children, side = 'top', sideOffset = 4 }, ref) => { return ( } title={children} placement={side} arrow @@ -63,9 +63,8 @@ const TooltipContent = forwardRef( }, }, }} - {...props} > - {props.children} + {children} ) } diff --git a/frontends/nextjs/src/components/ui/organisms/Command.tsx b/frontends/nextjs/src/components/ui/organisms/Command.tsx index 0205ac549..ca76413a4 100644 --- a/frontends/nextjs/src/components/ui/organisms/Command.tsx +++ b/frontends/nextjs/src/components/ui/organisms/Command.tsx @@ -14,10 +14,34 @@ import { Divider, Typography, Paper, - Kbd, } from '@mui/material' import SearchIcon from '@mui/icons-material/Search' +// Custom Kbd component since MUI doesn't export one +const Kbd = ({ children, ...props }: { children: ReactNode; [key: string]: unknown }) => ( + + {children} + +) + // Types interface CommandItem { id: string diff --git a/frontends/nextjs/src/components/ui/organisms/Navigation.tsx b/frontends/nextjs/src/components/ui/organisms/Navigation.tsx index 317042c3e..f632884d2 100644 --- a/frontends/nextjs/src/components/ui/organisms/Navigation.tsx +++ b/frontends/nextjs/src/components/ui/organisms/Navigation.tsx @@ -246,7 +246,6 @@ const NavigationLink = forwardRef( return ( { describe('DEFAULT_USERS', () => { diff --git a/frontends/nextjs/src/lib/auth.ts b/frontends/nextjs/src/lib/auth/auth.ts similarity index 100% rename from frontends/nextjs/src/lib/auth.ts rename to frontends/nextjs/src/lib/auth/auth.ts diff --git a/frontends/nextjs/src/lib/auth/can-access-level.ts b/frontends/nextjs/src/lib/auth/can-access-level.ts index 3a1073889..85abab158 100644 --- a/frontends/nextjs/src/lib/auth/can-access-level.ts +++ b/frontends/nextjs/src/lib/auth/can-access-level.ts @@ -1,4 +1,4 @@ -import type { UserRole } from '../level-types' +import type { UserRole } from '../types/level-types' /** * Role hierarchy mapping roles to their numeric permission levels diff --git a/frontends/nextjs/src/lib/auth/default-users.ts b/frontends/nextjs/src/lib/auth/default-users.ts index 7b75dc481..8b59a1072 100644 --- a/frontends/nextjs/src/lib/auth/default-users.ts +++ b/frontends/nextjs/src/lib/auth/default-users.ts @@ -1,4 +1,4 @@ -import type { User } from '../level-types' +import type { User } from '../types/level-types' /** * Default users created during application initialization diff --git a/frontends/nextjs/src/lib/auth/get-role-display-name.ts b/frontends/nextjs/src/lib/auth/get-role-display-name.ts index 4b89ee94d..2e2026722 100644 --- a/frontends/nextjs/src/lib/auth/get-role-display-name.ts +++ b/frontends/nextjs/src/lib/auth/get-role-display-name.ts @@ -1,4 +1,4 @@ -import type { UserRole } from '../level-types' +import type { UserRole } from '../types/level-types' /** * Human-readable display names for user roles diff --git a/frontends/nextjs/src/lib/component-catalog.ts b/frontends/nextjs/src/lib/components/component-catalog.ts similarity index 100% rename from frontends/nextjs/src/lib/component-catalog.ts rename to frontends/nextjs/src/lib/components/component-catalog.ts diff --git a/frontends/nextjs/src/lib/component-registry.test.ts b/frontends/nextjs/src/lib/components/component-registry.test.ts similarity index 100% rename from frontends/nextjs/src/lib/component-registry.test.ts rename to frontends/nextjs/src/lib/components/component-registry.test.ts diff --git a/frontends/nextjs/src/lib/component-registry.ts b/frontends/nextjs/src/lib/components/component-registry.ts similarity index 100% rename from frontends/nextjs/src/lib/component-registry.ts rename to frontends/nextjs/src/lib/components/component-registry.ts diff --git a/frontends/nextjs/src/lib/components/index.ts b/frontends/nextjs/src/lib/components/index.ts new file mode 100644 index 000000000..cc2d3a4d5 --- /dev/null +++ b/frontends/nextjs/src/lib/components/index.ts @@ -0,0 +1,3 @@ +// Component system exports +export { componentCatalog, getComponentCatalog } from './component-catalog' +export { ComponentRegistry, getComponentRegistry } from './component-registry' diff --git a/frontends/nextjs/src/lib/database.ts b/frontends/nextjs/src/lib/database.ts index 0bb666464..70b357023 100644 --- a/frontends/nextjs/src/lib/database.ts +++ b/frontends/nextjs/src/lib/database.ts @@ -8,8 +8,8 @@ import type { Comment, Tenant, PowerTransferRequest, -} from './level-types' -import type { ModelSchema } from './schema-types' +} from '../types/level-types' +import type { ModelSchema } from './types/schema-types' import type { InstalledPackage } from './package-types' import type { SMTPConfig } from './password-utils' diff --git a/frontends/nextjs/src/lib/db/app-config/get-app-config.ts b/frontends/nextjs/src/lib/db/app-config/get-app-config.ts index d9cd64407..9a5ac1f3c 100644 --- a/frontends/nextjs/src/lib/db/app-config/get-app-config.ts +++ b/frontends/nextjs/src/lib/db/app-config/get-app-config.ts @@ -1,9 +1,11 @@ -import { prisma } from '../prisma' -import type { AppConfiguration } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { AppConfiguration } from '../../types/level-types' export async function getAppConfig(): Promise { - const config = await prisma.appConfiguration.findFirst() - if (!config) return null + const adapter = getAdapter() + const result = await adapter.list('AppConfiguration', { limit: 1 }) + if (result.data.length === 0) return null + const config = result.data[0] as any return { id: config.id, name: config.name, diff --git a/frontends/nextjs/src/lib/db/app-config/set-app-config.ts b/frontends/nextjs/src/lib/db/app-config/set-app-config.ts index 67d24c826..ba59e85d2 100644 --- a/frontends/nextjs/src/lib/db/app-config/set-app-config.ts +++ b/frontends/nextjs/src/lib/db/app-config/set-app-config.ts @@ -1,17 +1,23 @@ -import { prisma } from '../prisma' -import type { AppConfiguration } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { AppConfiguration } from '../../types/level-types' export async function setAppConfig(config: AppConfiguration): Promise { - await prisma.appConfiguration.deleteMany() - await prisma.appConfiguration.create({ - data: { - id: config.id, - name: config.name, - schemas: JSON.stringify(config.schemas), - workflows: JSON.stringify(config.workflows), - luaScripts: JSON.stringify(config.luaScripts), - pages: JSON.stringify(config.pages), - theme: JSON.stringify(config.theme), - }, + const adapter = getAdapter() + + // Delete existing configs + const existing = await adapter.list('AppConfiguration') + for (const c of existing.data as any[]) { + await adapter.delete('AppConfiguration', c.id) + } + + // Create new config + await adapter.create('AppConfiguration', { + id: config.id, + name: config.name, + schemas: JSON.stringify(config.schemas), + workflows: JSON.stringify(config.workflows), + luaScripts: JSON.stringify(config.luaScripts), + pages: JSON.stringify(config.pages), + theme: JSON.stringify(config.theme), }) } diff --git a/frontends/nextjs/src/lib/db/comments/add-comment.ts b/frontends/nextjs/src/lib/db/comments/add-comment.ts index a69baa918..18ab86eb5 100644 --- a/frontends/nextjs/src/lib/db/comments/add-comment.ts +++ b/frontends/nextjs/src/lib/db/comments/add-comment.ts @@ -1,15 +1,17 @@ -import { prisma } from '../prisma' -import type { Comment } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Comment } from '../../types/level-types' +/** + * Add a single comment + */ export async function addComment(comment: Comment): Promise { - await prisma.comment.create({ - data: { - id: comment.id, - userId: comment.userId, - content: comment.content, - createdAt: BigInt(comment.createdAt), - updatedAt: comment.updatedAt ? BigInt(comment.updatedAt) : null, - parentId: comment.parentId, - }, + const adapter = getAdapter() + await adapter.create('Comment', { + id: comment.id, + userId: comment.userId, + content: comment.content, + createdAt: BigInt(comment.createdAt), + updatedAt: comment.updatedAt ? BigInt(comment.updatedAt) : null, + parentId: comment.parentId, }) } diff --git a/frontends/nextjs/src/lib/db/comments/delete-comment.ts b/frontends/nextjs/src/lib/db/comments/delete-comment.ts index 6560ac968..03a8d36ac 100644 --- a/frontends/nextjs/src/lib/db/comments/delete-comment.ts +++ b/frontends/nextjs/src/lib/db/comments/delete-comment.ts @@ -1,5 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' +/** + * Delete a comment by ID + */ export async function deleteComment(commentId: string): Promise { - await prisma.comment.delete({ where: { id: commentId } }) + const adapter = getAdapter() + await adapter.delete('Comment', commentId) } diff --git a/frontends/nextjs/src/lib/db/comments/get-comments.ts b/frontends/nextjs/src/lib/db/comments/get-comments.ts index 9547b87dc..8b39a84d4 100644 --- a/frontends/nextjs/src/lib/db/comments/get-comments.ts +++ b/frontends/nextjs/src/lib/db/comments/get-comments.ts @@ -1,9 +1,13 @@ -import { prisma } from '../prisma' -import type { Comment } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Comment } from '../../types/level-types' +/** + * Get all comments from database + */ export async function getComments(): Promise { - const comments = await prisma.comment.findMany() - return comments.map((c) => ({ + const adapter = getAdapter() + const result = await adapter.list('Comment') + return (result.data as any[]).map((c) => ({ id: c.id, userId: c.userId, content: c.content, diff --git a/frontends/nextjs/src/lib/db/comments/set-comments.ts b/frontends/nextjs/src/lib/db/comments/set-comments.ts index 47e8a641e..e105042a7 100644 --- a/frontends/nextjs/src/lib/db/comments/set-comments.ts +++ b/frontends/nextjs/src/lib/db/comments/set-comments.ts @@ -1,18 +1,27 @@ -import { prisma } from '../prisma' -import type { Comment } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Comment } from '../../types/level-types' +/** + * Set all comments (replaces existing) + */ export async function setComments(comments: Comment[]): Promise { - await prisma.comment.deleteMany() + const adapter = getAdapter() + + // Delete existing comments + const existing = await adapter.list('Comment') + for (const c of existing.data as any[]) { + await adapter.delete('Comment', c.id) + } + + // Create new comments for (const comment of comments) { - await prisma.comment.create({ - data: { - id: comment.id, - userId: comment.userId, - content: comment.content, - createdAt: BigInt(comment.createdAt), - updatedAt: comment.updatedAt ? BigInt(comment.updatedAt) : null, - parentId: comment.parentId, - }, + await adapter.create('Comment', { + id: comment.id, + userId: comment.userId, + content: comment.content, + createdAt: BigInt(comment.createdAt), + updatedAt: comment.updatedAt ? BigInt(comment.updatedAt) : null, + parentId: comment.parentId, }) } } diff --git a/frontends/nextjs/src/lib/db/comments/update-comment.ts b/frontends/nextjs/src/lib/db/comments/update-comment.ts index 1ecf0d8c4..b2d5fb20f 100644 --- a/frontends/nextjs/src/lib/db/comments/update-comment.ts +++ b/frontends/nextjs/src/lib/db/comments/update-comment.ts @@ -1,9 +1,13 @@ -import { prisma } from '../prisma' -import type { Comment } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Comment } from '../../types/level-types' +/** + * Update a comment by ID + */ export async function updateComment(commentId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.content !== undefined) data.content = updates.content if (updates.updatedAt !== undefined) data.updatedAt = BigInt(updates.updatedAt) - await prisma.comment.update({ where: { id: commentId }, data }) + await adapter.update('Comment', commentId, data) } diff --git a/frontends/nextjs/src/lib/db/components/add-component-config.ts b/frontends/nextjs/src/lib/db/components/add-component-config.ts index 23b1f57e9..39dd002ca 100644 --- a/frontends/nextjs/src/lib/db/components/add-component-config.ts +++ b/frontends/nextjs/src/lib/db/components/add-component-config.ts @@ -1,15 +1,14 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import type { ComponentConfig } from '../types' export async function addComponentConfig(config: ComponentConfig): Promise { - await prisma.componentConfig.create({ - data: { - id: config.id, - componentId: config.componentId, - props: JSON.stringify(config.props), - styles: JSON.stringify(config.styles), - events: JSON.stringify(config.events), - conditionalRendering: config.conditionalRendering ? JSON.stringify(config.conditionalRendering) : null, - }, + const adapter = getAdapter() + await adapter.create('ComponentConfig', { + id: config.id, + componentId: config.componentId, + props: JSON.stringify(config.props), + styles: JSON.stringify(config.styles), + events: JSON.stringify(config.events), + conditionalRendering: config.conditionalRendering ? JSON.stringify(config.conditionalRendering) : null, }) } diff --git a/frontends/nextjs/src/lib/db/components/add-component-node.ts b/frontends/nextjs/src/lib/db/components/add-component-node.ts index 8c85a4b09..704e0f5ee 100644 --- a/frontends/nextjs/src/lib/db/components/add-component-node.ts +++ b/frontends/nextjs/src/lib/db/components/add-component-node.ts @@ -1,15 +1,14 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import type { ComponentNode } from '../types' export async function addComponentNode(node: ComponentNode): Promise { - await prisma.componentNode.create({ - data: { - id: node.id, - type: node.type, - parentId: node.parentId, - childIds: JSON.stringify(node.childIds), - order: node.order, - pageId: node.pageId, - }, + const adapter = getAdapter() + await adapter.create('ComponentNode', { + id: node.id, + type: node.type, + parentId: node.parentId, + childIds: JSON.stringify(node.childIds), + order: node.order, + pageId: node.pageId, }) } diff --git a/frontends/nextjs/src/lib/db/components/delete-component-config.ts b/frontends/nextjs/src/lib/db/components/delete-component-config.ts index beb2c06a8..844cb1e52 100644 --- a/frontends/nextjs/src/lib/db/components/delete-component-config.ts +++ b/frontends/nextjs/src/lib/db/components/delete-component-config.ts @@ -1,5 +1,6 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' export async function deleteComponentConfig(configId: string): Promise { - await prisma.componentConfig.delete({ where: { id: configId } }) + const adapter = getAdapter() + await adapter.delete('ComponentConfig', configId) } diff --git a/frontends/nextjs/src/lib/db/components/delete-component-node.ts b/frontends/nextjs/src/lib/db/components/delete-component-node.ts index 0e955c237..695f55f21 100644 --- a/frontends/nextjs/src/lib/db/components/delete-component-node.ts +++ b/frontends/nextjs/src/lib/db/components/delete-component-node.ts @@ -1,5 +1,6 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' export async function deleteComponentNode(nodeId: string): Promise { - await prisma.componentNode.delete({ where: { id: nodeId } }) + const adapter = getAdapter() + await adapter.delete('ComponentNode', nodeId) } diff --git a/frontends/nextjs/src/lib/db/components/get-component-configs.ts b/frontends/nextjs/src/lib/db/components/get-component-configs.ts index 264f021d0..b116ebb93 100644 --- a/frontends/nextjs/src/lib/db/components/get-component-configs.ts +++ b/frontends/nextjs/src/lib/db/components/get-component-configs.ts @@ -1,11 +1,12 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import type { ComponentConfig } from '../types' export async function getComponentConfigs(): Promise> { - const configs = await prisma.componentConfig.findMany() - const result: Record = {} - for (const config of configs) { - result[config.id] = { + const adapter = getAdapter() + const result = await adapter.list('ComponentConfig') + const configs: Record = {} + for (const config of result.data as any[]) { + configs[config.id] = { id: config.id, componentId: config.componentId, props: JSON.parse(config.props), @@ -14,5 +15,5 @@ export async function getComponentConfigs(): Promise> { - const nodes = await prisma.componentNode.findMany() - const result: Record = {} - for (const node of nodes) { - result[node.id] = { + const adapter = getAdapter() + const result = await adapter.list('ComponentNode') + const hierarchy: Record = {} + for (const node of result.data as any[]) { + hierarchy[node.id] = { id: node.id, type: node.type, parentId: node.parentId || undefined, @@ -14,5 +15,5 @@ export async function getComponentHierarchy(): Promise): Promise { - await prisma.componentConfig.deleteMany() + const adapter = getAdapter() + + // Delete existing configs + const existing = await adapter.list('ComponentConfig') + for (const c of existing.data as any[]) { + await adapter.delete('ComponentConfig', c.id) + } + + // Create new configs for (const config of Object.values(configs)) { - await prisma.componentConfig.create({ - data: { - id: config.id, - componentId: config.componentId, - props: JSON.stringify(config.props), - styles: JSON.stringify(config.styles), - events: JSON.stringify(config.events), - conditionalRendering: config.conditionalRendering ? JSON.stringify(config.conditionalRendering) : null, - }, + await adapter.create('ComponentConfig', { + id: config.id, + componentId: config.componentId, + props: JSON.stringify(config.props), + styles: JSON.stringify(config.styles), + events: JSON.stringify(config.events), + conditionalRendering: config.conditionalRendering ? JSON.stringify(config.conditionalRendering) : null, }) } } diff --git a/frontends/nextjs/src/lib/db/components/set-component-hierarchy.ts b/frontends/nextjs/src/lib/db/components/set-component-hierarchy.ts index 1005c576f..383193e0c 100644 --- a/frontends/nextjs/src/lib/db/components/set-component-hierarchy.ts +++ b/frontends/nextjs/src/lib/db/components/set-component-hierarchy.ts @@ -1,18 +1,24 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import type { ComponentNode } from '../types' export async function setComponentHierarchy(hierarchy: Record): Promise { - await prisma.componentNode.deleteMany() + const adapter = getAdapter() + + // Delete existing hierarchy + const existing = await adapter.list('ComponentNode') + for (const n of existing.data as any[]) { + await adapter.delete('ComponentNode', n.id) + } + + // Create new hierarchy for (const node of Object.values(hierarchy)) { - await prisma.componentNode.create({ - data: { - id: node.id, - type: node.type, - parentId: node.parentId, - childIds: JSON.stringify(node.childIds), - order: node.order, - pageId: node.pageId, - }, + await adapter.create('ComponentNode', { + id: node.id, + type: node.type, + parentId: node.parentId, + childIds: JSON.stringify(node.childIds), + order: node.order, + pageId: node.pageId, }) } } diff --git a/frontends/nextjs/src/lib/db/components/update-component-config.ts b/frontends/nextjs/src/lib/db/components/update-component-config.ts index 16bb90552..d9224db7c 100644 --- a/frontends/nextjs/src/lib/db/components/update-component-config.ts +++ b/frontends/nextjs/src/lib/db/components/update-component-config.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import type { ComponentConfig } from '../types' export async function updateComponentConfig(configId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.componentId !== undefined) data.componentId = updates.componentId if (updates.props !== undefined) data.props = JSON.stringify(updates.props) if (updates.styles !== undefined) data.styles = JSON.stringify(updates.styles) @@ -10,5 +11,5 @@ export async function updateComponentConfig(configId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.type !== undefined) data.type = updates.type if (updates.parentId !== undefined) data.parentId = updates.parentId if (updates.childIds !== undefined) data.childIds = JSON.stringify(updates.childIds) if (updates.order !== undefined) data.order = updates.order if (updates.pageId !== undefined) data.pageId = updates.pageId - await prisma.componentNode.update({ where: { id: nodeId }, data }) + await adapter.update('ComponentNode', nodeId, data) } diff --git a/frontends/nextjs/src/lib/db/credentials/delete-password-reset-token.ts b/frontends/nextjs/src/lib/db/credentials/delete-password-reset-token.ts index a3be5a1cc..8c91f5cb8 100644 --- a/frontends/nextjs/src/lib/db/credentials/delete-password-reset-token.ts +++ b/frontends/nextjs/src/lib/db/credentials/delete-password-reset-token.ts @@ -1,15 +1,19 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import { getPasswordResetTokens } from './get-password-reset-tokens' /** * Delete a password reset token */ export async function deletePasswordResetToken(username: string): Promise { + const adapter = getAdapter() const tokens = await getPasswordResetTokens() delete tokens[username] - await prisma.keyValue.upsert({ - where: { key: 'db_password_reset_tokens' }, - update: { value: JSON.stringify(tokens) }, - create: { key: 'db_password_reset_tokens', value: JSON.stringify(tokens) }, - }) + + const existing = await adapter.list('KeyValue', { filter: { key: 'db_password_reset_tokens' } }) + if (existing.data.length > 0) { + const kv = existing.data[0] as any + await adapter.update('KeyValue', kv.id || kv.key, { value: JSON.stringify(tokens) }) + } else { + await adapter.create('KeyValue', { key: 'db_password_reset_tokens', value: JSON.stringify(tokens) }) + } } diff --git a/frontends/nextjs/src/lib/db/credentials/get-credentials.ts b/frontends/nextjs/src/lib/db/credentials/get-credentials.ts index 98944aa7b..9feb045ce 100644 --- a/frontends/nextjs/src/lib/db/credentials/get-credentials.ts +++ b/frontends/nextjs/src/lib/db/credentials/get-credentials.ts @@ -1,13 +1,14 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Get all credentials as a username->passwordHash map */ export async function getCredentials(): Promise> { - const credentials = await prisma.credential.findMany() - const result: Record = {} - for (const cred of credentials) { - result[cred.username] = cred.passwordHash + const adapter = getAdapter() + const result = await adapter.list('Credential') + const credentials: Record = {} + for (const cred of result.data as any[]) { + credentials[cred.username] = cred.passwordHash } - return result + return credentials } diff --git a/frontends/nextjs/src/lib/db/credentials/get-password-change-timestamps.ts b/frontends/nextjs/src/lib/db/credentials/get-password-change-timestamps.ts index 3d70a3934..f2d75eb54 100644 --- a/frontends/nextjs/src/lib/db/credentials/get-password-change-timestamps.ts +++ b/frontends/nextjs/src/lib/db/credentials/get-password-change-timestamps.ts @@ -1,18 +1,16 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Get password change timestamps for all users */ export async function getPasswordChangeTimestamps(): Promise> { - const users = await prisma.user.findMany({ - where: { passwordChangeTimestamp: { not: null } }, - select: { username: true, passwordChangeTimestamp: true }, - }) - const result: Record = {} - for (const user of users) { + const adapter = getAdapter() + const result = await adapter.list('User') + const timestamps: Record = {} + for (const user of result.data as any[]) { if (user.passwordChangeTimestamp) { - result[user.username] = Number(user.passwordChangeTimestamp) + timestamps[user.username] = Number(user.passwordChangeTimestamp) } } - return result + return timestamps } diff --git a/frontends/nextjs/src/lib/db/credentials/get-password-reset-tokens.ts b/frontends/nextjs/src/lib/db/credentials/get-password-reset-tokens.ts index ae69bcd23..5c0ca4055 100644 --- a/frontends/nextjs/src/lib/db/credentials/get-password-reset-tokens.ts +++ b/frontends/nextjs/src/lib/db/credentials/get-password-reset-tokens.ts @@ -1,9 +1,12 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Get password reset tokens */ export async function getPasswordResetTokens(): Promise> { - const kv = await prisma.keyValue.findUnique({ where: { key: 'db_password_reset_tokens' } }) + const adapter = getAdapter() + const result = await adapter.list('KeyValue', { filter: { key: 'db_password_reset_tokens' } }) + if (result.data.length === 0) return {} + const kv = result.data[0] as any return kv ? JSON.parse(kv.value) : {} } diff --git a/frontends/nextjs/src/lib/db/credentials/set-credential.ts b/frontends/nextjs/src/lib/db/credentials/set-credential.ts index aeffe8965..fcbc09ff0 100644 --- a/frontends/nextjs/src/lib/db/credentials/set-credential.ts +++ b/frontends/nextjs/src/lib/db/credentials/set-credential.ts @@ -1,17 +1,27 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Set or update a user's credential */ export async function setCredential(username: string, passwordHash: string): Promise { - await prisma.credential.upsert({ - where: { username }, - update: { passwordHash }, - create: { username, passwordHash }, - }) + const adapter = getAdapter() + + // Check if credential exists + const result = await adapter.list('Credential', { filter: { username } }) + + if (result.data.length > 0) { + // Update existing + const existing = result.data[0] as any + await adapter.update('Credential', existing.id || existing.username, { passwordHash }) + } else { + // Create new + await adapter.create('Credential', { username, passwordHash }) + } - await prisma.user.update({ - where: { username }, - data: { passwordChangeTimestamp: BigInt(Date.now()) }, - }) + // Update password change timestamp on user + const users = await adapter.list('User', { filter: { username } }) + if (users.data.length > 0) { + const user = users.data[0] as any + await adapter.update('User', user.id, { passwordChangeTimestamp: BigInt(Date.now()) }) + } } diff --git a/frontends/nextjs/src/lib/db/credentials/set-password-change-timestamps.ts b/frontends/nextjs/src/lib/db/credentials/set-password-change-timestamps.ts index 0844e247c..19e7d3dd3 100644 --- a/frontends/nextjs/src/lib/db/credentials/set-password-change-timestamps.ts +++ b/frontends/nextjs/src/lib/db/credentials/set-password-change-timestamps.ts @@ -1,13 +1,15 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Set password change timestamps for users */ export async function setPasswordChangeTimestamps(timestamps: Record): Promise { + const adapter = getAdapter() for (const [username, timestamp] of Object.entries(timestamps)) { - await prisma.user.update({ - where: { username }, - data: { passwordChangeTimestamp: BigInt(timestamp) }, - }) + const users = await adapter.list('User', { filter: { username } }) + if (users.data.length > 0) { + const user = users.data[0] as any + await adapter.update('User', user.id, { passwordChangeTimestamp: BigInt(timestamp) }) + } } } diff --git a/frontends/nextjs/src/lib/db/credentials/set-password-reset-token.ts b/frontends/nextjs/src/lib/db/credentials/set-password-reset-token.ts index 4bc278156..1185b9ad1 100644 --- a/frontends/nextjs/src/lib/db/credentials/set-password-reset-token.ts +++ b/frontends/nextjs/src/lib/db/credentials/set-password-reset-token.ts @@ -1,15 +1,19 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' import { getPasswordResetTokens } from './get-password-reset-tokens' /** * Set a password reset token for a user */ export async function setPasswordResetToken(username: string, token: string): Promise { + const adapter = getAdapter() const tokens = await getPasswordResetTokens() tokens[username] = token - await prisma.keyValue.upsert({ - where: { key: 'db_password_reset_tokens' }, - update: { value: JSON.stringify(tokens) }, - create: { key: 'db_password_reset_tokens', value: JSON.stringify(tokens) }, - }) + + const existing = await adapter.list('KeyValue', { filter: { key: 'db_password_reset_tokens' } }) + if (existing.data.length > 0) { + const kv = existing.data[0] as any + await adapter.update('KeyValue', kv.id || kv.key, { value: JSON.stringify(tokens) }) + } else { + await adapter.create('KeyValue', { key: 'db_password_reset_tokens', value: JSON.stringify(tokens) }) + } } diff --git a/frontends/nextjs/src/lib/db/credentials/verify-credentials.ts b/frontends/nextjs/src/lib/db/credentials/verify-credentials.ts index a561d5f0c..df9cdf5f6 100644 --- a/frontends/nextjs/src/lib/db/credentials/verify-credentials.ts +++ b/frontends/nextjs/src/lib/db/credentials/verify-credentials.ts @@ -1,11 +1,13 @@ -import { prisma } from '../prisma' -import { verifyPassword } from '../hash-password' +import { getAdapter } from '../dbal-client' +import { verifyPassword } from '../verify-password' /** * Verify username/password combination */ export async function verifyCredentials(username: string, password: string): Promise { - const credential = await prisma.credential.findUnique({ where: { username } }) - if (!credential) return false + const adapter = getAdapter() + const result = await adapter.list('Credential', { filter: { username } }) + if (result.data.length === 0) return false + const credential = result.data[0] as any return await verifyPassword(password, credential.passwordHash) } diff --git a/frontends/nextjs/src/lib/db/dbal-client.ts b/frontends/nextjs/src/lib/db/dbal-client.ts new file mode 100644 index 000000000..599c59991 --- /dev/null +++ b/frontends/nextjs/src/lib/db/dbal-client.ts @@ -0,0 +1,142 @@ +/** + * DBAL Client Singleton + * + * Provides centralized access to the Database Abstraction Layer. + * All db/ lambda functions should use this instead of importing Prisma directly. + * + * This uses the PrismaClient directly but wraps it in a DBAL-compatible interface, + * providing a migration path to the full DBAL when ready. + */ + +import { prisma } from '../prisma' + +export interface ListOptions { + filter?: Record + sort?: Record + page?: number + limit?: number +} + +export interface ListResult { + data: T[] + total?: number + page?: number + limit?: number + hasMore?: boolean +} + +export interface DBALAdapter { + create(entity: string, data: Record): Promise + read(entity: string, id: string): Promise + update(entity: string, id: string, data: Record): Promise + delete(entity: string, id: string): Promise + list(entity: string, options?: ListOptions): Promise> + close(): Promise +} + +/** + * Get the Prisma model by entity name + */ +const getModel = (entity: string): any => { + const modelName = entity.charAt(0).toLowerCase() + entity.slice(1) + const model = (prisma as any)[modelName] + if (!model) { + throw new Error(`Entity ${entity} not found in Prisma schema`) + } + return model +} + +/** + * Build where clause from filter + */ +const buildWhereClause = (filter: Record): Record => { + const where: Record = {} + for (const [key, value] of Object.entries(filter)) { + if (value !== undefined) { + where[key] = value + } + } + return where +} + +/** + * DBAL Adapter implementation using Prisma + */ +const prismaAdapter: DBALAdapter = { + async create(entity: string, data: Record): Promise { + const model = getModel(entity) + return model.create({ data }) + }, + + async read(entity: string, id: string): Promise { + const model = getModel(entity) + return model.findUnique({ where: { id } }) + }, + + async update(entity: string, id: string, data: Record): Promise { + const model = getModel(entity) + // Filter out undefined values + const cleanData: Record = {} + for (const [key, value] of Object.entries(data)) { + if (value !== undefined) { + cleanData[key] = value + } + } + return model.update({ where: { id }, data: cleanData }) + }, + + async delete(entity: string, id: string): Promise { + const model = getModel(entity) + try { + await model.delete({ where: { id } }) + return true + } catch { + return false + } + }, + + async list(entity: string, options?: ListOptions): Promise> { + const model = getModel(entity) + const page = options?.page || 1 + const limit = options?.limit || 1000 + const skip = (page - 1) * limit + const where = options?.filter ? buildWhereClause(options.filter) : undefined + const orderBy = options?.sort + + const [data, total] = await Promise.all([ + model.findMany({ + where, + orderBy, + skip, + take: limit, + }), + model.count({ where }), + ]) + + return { + data, + total, + page, + limit, + hasMore: skip + limit < total, + } + }, + + async close(): Promise { + await prisma.$disconnect() + }, +} + +/** + * Get the DBAL adapter singleton for database operations + */ +export const getAdapter = (): DBALAdapter => { + return prismaAdapter +} + +/** + * Close the DBAL adapter connection + */ +export const closeAdapter = async (): Promise => { + await prismaAdapter.close() +} diff --git a/frontends/nextjs/src/lib/db/index.ts b/frontends/nextjs/src/lib/db/index.ts index afb2469cd..fe3354828 100644 --- a/frontends/nextjs/src/lib/db/index.ts +++ b/frontends/nextjs/src/lib/db/index.ts @@ -1,6 +1,10 @@ // Types export type { CssCategory, DropdownConfig, DatabaseSchema, ComponentNode, ComponentConfig } from './types' +// DBAL Client +export { getAdapter, closeAdapter } from './dbal-client' +export type { DBALAdapter, ListOptions, ListResult } from './dbal-client' + // Core export { hashPassword } from './hash-password' export { verifyPassword } from './verify-password' @@ -13,6 +17,9 @@ export * from './workflows' export * from './lua-scripts' export * from './pages' export * from './schemas' +export * from './comments' +export * from './app-config' +export * from './components' // Import all for namespace class import { initializeDatabase } from './initialize-database' @@ -24,6 +31,9 @@ import * as workflows from './workflows' import * as luaScripts from './lua-scripts' import * as pages from './pages' import * as schemas from './schemas' +import * as comments from './comments' +import * as appConfig from './app-config' +import * as components from './components' /** * Database namespace class - groups all DB operations as static methods @@ -81,4 +91,27 @@ export class Database { static addSchema = schemas.addSchema static updateSchema = schemas.updateSchema static deleteSchema = schemas.deleteSchema + + // Comments + static getComments = comments.getComments + static setComments = comments.setComments + static addComment = comments.addComment + static updateComment = comments.updateComment + static deleteComment = comments.deleteComment + + // App Config + static getAppConfig = appConfig.getAppConfig + static setAppConfig = appConfig.setAppConfig + + // Components + static getComponentHierarchy = components.getComponentHierarchy + static setComponentHierarchy = components.setComponentHierarchy + static addComponentNode = components.addComponentNode + static updateComponentNode = components.updateComponentNode + static deleteComponentNode = components.deleteComponentNode + static getComponentConfigs = components.getComponentConfigs + static setComponentConfigs = components.setComponentConfigs + static addComponentConfig = components.addComponentConfig + static updateComponentConfig = components.updateComponentConfig + static deleteComponentConfig = components.deleteComponentConfig } diff --git a/frontends/nextjs/src/lib/db/lua-scripts/add-lua-script.ts b/frontends/nextjs/src/lib/db/lua-scripts/add-lua-script.ts index 570ca8a08..800bec9ce 100644 --- a/frontends/nextjs/src/lib/db/lua-scripts/add-lua-script.ts +++ b/frontends/nextjs/src/lib/db/lua-scripts/add-lua-script.ts @@ -1,18 +1,17 @@ -import { prisma } from '../prisma' -import type { LuaScript } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { LuaScript } from '../../types/level-types' /** * Add a Lua script */ export async function addLuaScript(script: LuaScript): Promise { - await prisma.luaScript.create({ - data: { - id: script.id, - name: script.name, - description: script.description, - code: script.code, - parameters: JSON.stringify(script.parameters), - returnType: script.returnType, - }, + const adapter = getAdapter() + await adapter.create('LuaScript', { + id: script.id, + name: script.name, + description: script.description, + code: script.code, + parameters: JSON.stringify(script.parameters), + returnType: script.returnType, }) } diff --git a/frontends/nextjs/src/lib/db/lua-scripts/delete-lua-script.ts b/frontends/nextjs/src/lib/db/lua-scripts/delete-lua-script.ts index 0bddebb8e..7d723f9c7 100644 --- a/frontends/nextjs/src/lib/db/lua-scripts/delete-lua-script.ts +++ b/frontends/nextjs/src/lib/db/lua-scripts/delete-lua-script.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Delete a Lua script by ID */ export async function deleteLuaScript(scriptId: string): Promise { - await prisma.luaScript.delete({ where: { id: scriptId } }) + const adapter = getAdapter() + await adapter.delete('LuaScript', scriptId) } diff --git a/frontends/nextjs/src/lib/db/lua-scripts/get-lua-scripts.ts b/frontends/nextjs/src/lib/db/lua-scripts/get-lua-scripts.ts index c81fe27d8..5efeb017f 100644 --- a/frontends/nextjs/src/lib/db/lua-scripts/get-lua-scripts.ts +++ b/frontends/nextjs/src/lib/db/lua-scripts/get-lua-scripts.ts @@ -1,12 +1,13 @@ -import { prisma } from '../prisma' -import type { LuaScript } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { LuaScript } from '../../types/level-types' /** * Get all Lua scripts */ export async function getLuaScripts(): Promise { - const scripts = await prisma.luaScript.findMany() - return scripts.map((s) => ({ + const adapter = getAdapter() + const result = await adapter.list('LuaScript') + return (result.data as any[]).map((s) => ({ id: s.id, name: s.name, description: s.description || undefined, diff --git a/frontends/nextjs/src/lib/db/lua-scripts/set-lua-scripts.ts b/frontends/nextjs/src/lib/db/lua-scripts/set-lua-scripts.ts index dacb6182c..f991d2109 100644 --- a/frontends/nextjs/src/lib/db/lua-scripts/set-lua-scripts.ts +++ b/frontends/nextjs/src/lib/db/lua-scripts/set-lua-scripts.ts @@ -1,21 +1,27 @@ -import { prisma } from '../prisma' -import type { LuaScript } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { LuaScript } from '../../types/level-types' /** * Set all Lua scripts (replaces existing) */ export async function setLuaScripts(scripts: LuaScript[]): Promise { - await prisma.luaScript.deleteMany() + const adapter = getAdapter() + + // Delete existing scripts + const existing = await adapter.list('LuaScript') + for (const s of existing.data as any[]) { + await adapter.delete('LuaScript', s.id) + } + + // Create new scripts for (const script of scripts) { - await prisma.luaScript.create({ - data: { - id: script.id, - name: script.name, - description: script.description, - code: script.code, - parameters: JSON.stringify(script.parameters), - returnType: script.returnType, - }, + await adapter.create('LuaScript', { + id: script.id, + name: script.name, + description: script.description, + code: script.code, + parameters: JSON.stringify(script.parameters), + returnType: script.returnType, }) } } diff --git a/frontends/nextjs/src/lib/db/lua-scripts/update-lua-script.ts b/frontends/nextjs/src/lib/db/lua-scripts/update-lua-script.ts index 4b8371f52..547432df6 100644 --- a/frontends/nextjs/src/lib/db/lua-scripts/update-lua-script.ts +++ b/frontends/nextjs/src/lib/db/lua-scripts/update-lua-script.ts @@ -1,19 +1,17 @@ -import { prisma } from '../prisma' -import type { LuaScript } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { LuaScript } from '../../types/level-types' /** * Update a Lua script by ID */ export async function updateLuaScript(scriptId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.name !== undefined) data.name = updates.name if (updates.description !== undefined) data.description = updates.description if (updates.code !== undefined) data.code = updates.code if (updates.parameters !== undefined) data.parameters = JSON.stringify(updates.parameters) if (updates.returnType !== undefined) data.returnType = updates.returnType - await prisma.luaScript.update({ - where: { id: scriptId }, - data, - }) + await adapter.update('LuaScript', scriptId, data) } diff --git a/frontends/nextjs/src/lib/db/pages/add-page.ts b/frontends/nextjs/src/lib/db/pages/add-page.ts index bb870cb74..23ff3a666 100644 --- a/frontends/nextjs/src/lib/db/pages/add-page.ts +++ b/frontends/nextjs/src/lib/db/pages/add-page.ts @@ -1,19 +1,18 @@ -import { prisma } from '../prisma' -import type { PageConfig } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { PageConfig } from '../../types/level-types' /** * Add a page */ export async function addPage(page: PageConfig): Promise { - await prisma.pageConfig.create({ - data: { - id: page.id, - path: page.path, - title: page.title, - level: page.level, - componentTree: JSON.stringify(page.componentTree), - requiresAuth: page.requiresAuth, - requiredRole: page.requiredRole, - }, + const adapter = getAdapter() + await adapter.create('PageConfig', { + id: page.id, + path: page.path, + title: page.title, + level: page.level, + componentTree: JSON.stringify(page.componentTree), + requiresAuth: page.requiresAuth, + requiredRole: page.requiredRole, }) } diff --git a/frontends/nextjs/src/lib/db/pages/delete-page.ts b/frontends/nextjs/src/lib/db/pages/delete-page.ts index 9813b967b..0fc9b5420 100644 --- a/frontends/nextjs/src/lib/db/pages/delete-page.ts +++ b/frontends/nextjs/src/lib/db/pages/delete-page.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Delete a page by ID */ export async function deletePage(pageId: string): Promise { - await prisma.pageConfig.delete({ where: { id: pageId } }) + const adapter = getAdapter() + await adapter.delete('PageConfig', pageId) } diff --git a/frontends/nextjs/src/lib/db/pages/get-pages.ts b/frontends/nextjs/src/lib/db/pages/get-pages.ts index 811c4ccd3..e1edd2aff 100644 --- a/frontends/nextjs/src/lib/db/pages/get-pages.ts +++ b/frontends/nextjs/src/lib/db/pages/get-pages.ts @@ -1,12 +1,13 @@ -import { prisma } from '../prisma' -import type { PageConfig } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { PageConfig } from '../../types/level-types' /** * Get all pages */ export async function getPages(): Promise { - const pages = await prisma.pageConfig.findMany() - return pages.map((p) => ({ + const adapter = getAdapter() + const result = await adapter.list('PageConfig') + return (result.data as any[]).map((p) => ({ id: p.id, path: p.path, title: p.title, diff --git a/frontends/nextjs/src/lib/db/pages/set-pages.ts b/frontends/nextjs/src/lib/db/pages/set-pages.ts index 61b60bd71..820d32b17 100644 --- a/frontends/nextjs/src/lib/db/pages/set-pages.ts +++ b/frontends/nextjs/src/lib/db/pages/set-pages.ts @@ -1,22 +1,28 @@ -import { prisma } from '../prisma' -import type { PageConfig } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { PageConfig } from '../../types/level-types' /** * Set all pages (replaces existing) */ export async function setPages(pages: PageConfig[]): Promise { - await prisma.pageConfig.deleteMany() + const adapter = getAdapter() + + // Delete existing pages + const existing = await adapter.list('PageConfig') + for (const p of existing.data as any[]) { + await adapter.delete('PageConfig', p.id) + } + + // Create new pages for (const page of pages) { - await prisma.pageConfig.create({ - data: { - id: page.id, - path: page.path, - title: page.title, - level: page.level, - componentTree: JSON.stringify(page.componentTree), - requiresAuth: page.requiresAuth, - requiredRole: page.requiredRole, - }, + await adapter.create('PageConfig', { + id: page.id, + path: page.path, + title: page.title, + level: page.level, + componentTree: JSON.stringify(page.componentTree), + requiresAuth: page.requiresAuth, + requiredRole: page.requiredRole, }) } } diff --git a/frontends/nextjs/src/lib/db/pages/update-page.ts b/frontends/nextjs/src/lib/db/pages/update-page.ts index a35e90444..323528700 100644 --- a/frontends/nextjs/src/lib/db/pages/update-page.ts +++ b/frontends/nextjs/src/lib/db/pages/update-page.ts @@ -1,11 +1,12 @@ -import { prisma } from '../prisma' -import type { PageConfig } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { PageConfig } from '../../types/level-types' /** * Update a page by ID */ export async function updatePage(pageId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.path !== undefined) data.path = updates.path if (updates.title !== undefined) data.title = updates.title if (updates.level !== undefined) data.level = updates.level @@ -13,8 +14,5 @@ export async function updatePage(pageId: string, updates: Partial): if (updates.requiresAuth !== undefined) data.requiresAuth = updates.requiresAuth if (updates.requiredRole !== undefined) data.requiredRole = updates.requiredRole - await prisma.pageConfig.update({ - where: { id: pageId }, - data, - }) + await adapter.update('PageConfig', pageId, data) } diff --git a/frontends/nextjs/src/lib/db/schemas/add-schema.ts b/frontends/nextjs/src/lib/db/schemas/add-schema.ts index 25d1bb936..3062f333b 100644 --- a/frontends/nextjs/src/lib/db/schemas/add-schema.ts +++ b/frontends/nextjs/src/lib/db/schemas/add-schema.ts @@ -1,21 +1,20 @@ -import { prisma } from '../prisma' -import type { ModelSchema } from '../../schema-types' +import { getAdapter } from '../dbal-client' +import type { ModelSchema } from '../../types/schema-types' /** * Add a schema */ export async function addSchema(schema: ModelSchema): Promise { - await prisma.modelSchema.create({ - data: { - name: schema.name, - label: schema.label, - labelPlural: schema.labelPlural, - icon: schema.icon, - fields: JSON.stringify(schema.fields), - listDisplay: schema.listDisplay ? JSON.stringify(schema.listDisplay) : null, - listFilter: schema.listFilter ? JSON.stringify(schema.listFilter) : null, - searchFields: schema.searchFields ? JSON.stringify(schema.searchFields) : null, - ordering: schema.ordering ? JSON.stringify(schema.ordering) : null, - }, + const adapter = getAdapter() + await adapter.create('ModelSchema', { + name: schema.name, + label: schema.label, + labelPlural: schema.labelPlural, + icon: schema.icon, + fields: JSON.stringify(schema.fields), + listDisplay: schema.listDisplay ? JSON.stringify(schema.listDisplay) : null, + listFilter: schema.listFilter ? JSON.stringify(schema.listFilter) : null, + searchFields: schema.searchFields ? JSON.stringify(schema.searchFields) : null, + ordering: schema.ordering ? JSON.stringify(schema.ordering) : null, }) } diff --git a/frontends/nextjs/src/lib/db/schemas/delete-schema.ts b/frontends/nextjs/src/lib/db/schemas/delete-schema.ts index edff94836..603fa839f 100644 --- a/frontends/nextjs/src/lib/db/schemas/delete-schema.ts +++ b/frontends/nextjs/src/lib/db/schemas/delete-schema.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Delete a schema by name */ export async function deleteSchema(schemaName: string): Promise { - await prisma.modelSchema.delete({ where: { name: schemaName } }) + const adapter = getAdapter() + await adapter.delete('ModelSchema', schemaName) } diff --git a/frontends/nextjs/src/lib/db/schemas/get-schemas.ts b/frontends/nextjs/src/lib/db/schemas/get-schemas.ts index 24a52ee74..5f7bccc2b 100644 --- a/frontends/nextjs/src/lib/db/schemas/get-schemas.ts +++ b/frontends/nextjs/src/lib/db/schemas/get-schemas.ts @@ -1,12 +1,13 @@ -import { prisma } from '../prisma' -import type { ModelSchema } from '../../schema-types' +import { getAdapter } from '../dbal-client' +import type { ModelSchema } from '../../types/schema-types' /** * Get all schemas */ export async function getSchemas(): Promise { - const schemas = await prisma.modelSchema.findMany() - return schemas.map((s) => ({ + const adapter = getAdapter() + const result = await adapter.list('ModelSchema') + return (result.data as any[]).map((s) => ({ name: s.name, label: s.label || undefined, labelPlural: s.labelPlural || undefined, diff --git a/frontends/nextjs/src/lib/db/schemas/set-schemas.ts b/frontends/nextjs/src/lib/db/schemas/set-schemas.ts index 0a5fbff09..111cd8b0e 100644 --- a/frontends/nextjs/src/lib/db/schemas/set-schemas.ts +++ b/frontends/nextjs/src/lib/db/schemas/set-schemas.ts @@ -1,24 +1,30 @@ -import { prisma } from '../prisma' -import type { ModelSchema } from '../../schema-types' +import { getAdapter } from '../dbal-client' +import type { ModelSchema } from '../../types/schema-types' /** * Set all schemas (replaces existing) */ export async function setSchemas(schemas: ModelSchema[]): Promise { - await prisma.modelSchema.deleteMany() + const adapter = getAdapter() + + // Delete existing schemas + const existing = await adapter.list('ModelSchema') + for (const s of existing.data as any[]) { + await adapter.delete('ModelSchema', s.name) + } + + // Create new schemas for (const schema of schemas) { - await prisma.modelSchema.create({ - data: { - name: schema.name, - label: schema.label, - labelPlural: schema.labelPlural, - icon: schema.icon, - fields: JSON.stringify(schema.fields), - listDisplay: schema.listDisplay ? JSON.stringify(schema.listDisplay) : null, - listFilter: schema.listFilter ? JSON.stringify(schema.listFilter) : null, - searchFields: schema.searchFields ? JSON.stringify(schema.searchFields) : null, - ordering: schema.ordering ? JSON.stringify(schema.ordering) : null, - }, + await adapter.create('ModelSchema', { + name: schema.name, + label: schema.label, + labelPlural: schema.labelPlural, + icon: schema.icon, + fields: JSON.stringify(schema.fields), + listDisplay: schema.listDisplay ? JSON.stringify(schema.listDisplay) : null, + listFilter: schema.listFilter ? JSON.stringify(schema.listFilter) : null, + searchFields: schema.searchFields ? JSON.stringify(schema.searchFields) : null, + ordering: schema.ordering ? JSON.stringify(schema.ordering) : null, }) } } diff --git a/frontends/nextjs/src/lib/db/schemas/update-schema.ts b/frontends/nextjs/src/lib/db/schemas/update-schema.ts index 8823a5b9b..d0c93a719 100644 --- a/frontends/nextjs/src/lib/db/schemas/update-schema.ts +++ b/frontends/nextjs/src/lib/db/schemas/update-schema.ts @@ -1,11 +1,12 @@ -import { prisma } from '../prisma' -import type { ModelSchema } from '../../schema-types' +import { getAdapter } from '../dbal-client' +import type { ModelSchema } from '../../types/schema-types' /** * Update a schema by name */ export async function updateSchema(schemaName: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.label !== undefined) data.label = updates.label if (updates.labelPlural !== undefined) data.labelPlural = updates.labelPlural if (updates.icon !== undefined) data.icon = updates.icon @@ -15,8 +16,5 @@ export async function updateSchema(schemaName: string, updates: Partial - workflows: import('../level-types').Workflow[] - luaScripts: import('../level-types').LuaScript[] - pages: import('../level-types').PageConfig[] - schemas: import('../schema-types').ModelSchema[] - appConfig: import('../level-types').AppConfiguration - comments: import('../level-types').Comment[] + workflows: import('../types/level-types').Workflow[] + luaScripts: import('../types/level-types').LuaScript[] + pages: import('../types/level-types').PageConfig[] + schemas: import('../types/schema-types').ModelSchema[] + appConfig: import('../types/level-types').AppConfiguration + comments: import('../types/level-types').Comment[] componentHierarchy: Record componentConfigs: Record godCredentialsExpiry: number @@ -63,8 +63,8 @@ export interface DatabaseSchema { godCredentialsExpiryDuration: number cssClasses: CssCategory[] dropdownConfigs: DropdownConfig[] - tenants: import('../level-types').Tenant[] - powerTransferRequests: import('../level-types').PowerTransferRequest[] + tenants: import('../types/level-types').Tenant[] + powerTransferRequests: import('../types/level-types').PowerTransferRequest[] smtpConfig: import('../password').SMTPConfig passwordResetTokens: Record } diff --git a/frontends/nextjs/src/lib/db/users/add-user.ts b/frontends/nextjs/src/lib/db/users/add-user.ts index ba0f95ed9..8711d8aac 100644 --- a/frontends/nextjs/src/lib/db/users/add-user.ts +++ b/frontends/nextjs/src/lib/db/users/add-user.ts @@ -1,21 +1,20 @@ -import { prisma } from '../prisma' -import type { User } from '../level-types' +import { getAdapter } from '../dbal-client' +import type { User } from '../../types/level-types' /** * Add a single user */ export async function addUser(user: User): Promise { - await prisma.user.create({ - data: { - id: user.id, - username: user.username, - email: user.email, - role: user.role, - profilePicture: user.profilePicture, - bio: user.bio, - createdAt: BigInt(user.createdAt), - tenantId: user.tenantId, - isInstanceOwner: user.isInstanceOwner ?? false, - }, + const adapter = getAdapter() + await adapter.create('User', { + id: user.id, + username: user.username, + email: user.email, + role: user.role, + profilePicture: user.profilePicture, + bio: user.bio, + createdAt: BigInt(user.createdAt), + tenantId: user.tenantId, + isInstanceOwner: user.isInstanceOwner ?? false, }) } diff --git a/frontends/nextjs/src/lib/db/users/delete-user.ts b/frontends/nextjs/src/lib/db/users/delete-user.ts index 191d9f6b7..d6a6e02b9 100644 --- a/frontends/nextjs/src/lib/db/users/delete-user.ts +++ b/frontends/nextjs/src/lib/db/users/delete-user.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Delete a user by ID */ export async function deleteUser(userId: string): Promise { - await prisma.user.delete({ where: { id: userId } }) + const adapter = getAdapter() + await adapter.delete('User', userId) } diff --git a/frontends/nextjs/src/lib/db/users/get-super-god.ts b/frontends/nextjs/src/lib/db/users/get-super-god.ts index fe71bc12f..19ce7f005 100644 --- a/frontends/nextjs/src/lib/db/users/get-super-god.ts +++ b/frontends/nextjs/src/lib/db/users/get-super-god.ts @@ -1,15 +1,15 @@ -import { prisma } from '../prisma' -import type { User } from '../level-types' +import { getAdapter } from '../dbal-client' +import type { User } from '../../types/level-types' /** * Get the SuperGod user (instance owner) */ export async function getSuperGod(): Promise { - const user = await prisma.user.findFirst({ - where: { isInstanceOwner: true }, - }) + const adapter = getAdapter() + const result = await adapter.list('User', { filter: { isInstanceOwner: true } }) - if (!user) return null + if (result.data.length === 0) return null + const user = result.data[0] as any return { id: user.id, diff --git a/frontends/nextjs/src/lib/db/users/get-users.ts b/frontends/nextjs/src/lib/db/users/get-users.ts index 3f1c8ee24..e5bfc958e 100644 --- a/frontends/nextjs/src/lib/db/users/get-users.ts +++ b/frontends/nextjs/src/lib/db/users/get-users.ts @@ -1,12 +1,13 @@ -import { prisma } from '../prisma' -import type { User } from '../level-types' +import { getAdapter } from '../dbal-client' +import type { User } from '../../types/level-types' /** * Get all users from database */ export async function getUsers(): Promise { - const users = await prisma.user.findMany() - return users.map((u) => ({ + const adapter = getAdapter() + const result = await adapter.list('User') + return (result.data as any[]).map((u) => ({ id: u.id, username: u.username, email: u.email, diff --git a/frontends/nextjs/src/lib/db/users/set-users.ts b/frontends/nextjs/src/lib/db/users/set-users.ts index 91f9c74e1..24e6ae950 100644 --- a/frontends/nextjs/src/lib/db/users/set-users.ts +++ b/frontends/nextjs/src/lib/db/users/set-users.ts @@ -1,26 +1,31 @@ -import { prisma } from '../prisma' -import type { User } from '../level-types' +import { getAdapter } from '../dbal-client' +import type { User } from '../../types/level-types' /** * Set all users (replaces existing) + * Note: Uses sequential operations - for atomic transactions use prisma directly */ export async function setUsers(users: User[]): Promise { - await prisma.$transaction(async (tx) => { - await tx.user.deleteMany() - for (const user of users) { - await tx.user.create({ - data: { - id: user.id, - username: user.username, - email: user.email, - role: user.role, - profilePicture: user.profilePicture, - bio: user.bio, - createdAt: BigInt(user.createdAt), - tenantId: user.tenantId, - isInstanceOwner: user.isInstanceOwner ?? false, - }, - }) - } - }) + const adapter = getAdapter() + + // Get existing users and delete them + const existing = await adapter.list('User') + for (const user of existing.data as any[]) { + await adapter.delete('User', user.id) + } + + // Create new users + for (const user of users) { + await adapter.create('User', { + id: user.id, + username: user.username, + email: user.email, + role: user.role, + profilePicture: user.profilePicture, + bio: user.bio, + createdAt: BigInt(user.createdAt), + tenantId: user.tenantId, + isInstanceOwner: user.isInstanceOwner ?? false, + }) + } } diff --git a/frontends/nextjs/src/lib/db/users/transfer-super-god-power.ts b/frontends/nextjs/src/lib/db/users/transfer-super-god-power.ts index 0714db159..fe314480c 100644 --- a/frontends/nextjs/src/lib/db/users/transfer-super-god-power.ts +++ b/frontends/nextjs/src/lib/db/users/transfer-super-god-power.ts @@ -1,17 +1,10 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Transfer SuperGod power from one user to another */ export async function transferSuperGodPower(fromUserId: string, toUserId: string): Promise { - await prisma.$transaction([ - prisma.user.update({ - where: { id: fromUserId }, - data: { isInstanceOwner: false, role: 'god' }, - }), - prisma.user.update({ - where: { id: toUserId }, - data: { isInstanceOwner: true, role: 'supergod' }, - }), - ]) + const adapter = getAdapter() + await adapter.update('User', fromUserId, { isInstanceOwner: false, role: 'god' }) + await adapter.update('User', toUserId, { isInstanceOwner: true, role: 'supergod' }) } diff --git a/frontends/nextjs/src/lib/db/users/update-user.ts b/frontends/nextjs/src/lib/db/users/update-user.ts index d4de8606b..d7e88b327 100644 --- a/frontends/nextjs/src/lib/db/users/update-user.ts +++ b/frontends/nextjs/src/lib/db/users/update-user.ts @@ -1,20 +1,18 @@ -import { prisma } from '../prisma' -import type { User } from '../level-types' +import { getAdapter } from '../dbal-client' +import type { User } from '../../types/level-types' /** * Update a user by ID */ export async function updateUser(userId: string, updates: Partial): Promise { - await prisma.user.update({ - where: { id: userId }, - data: { - username: updates.username, - email: updates.email, - role: updates.role, - profilePicture: updates.profilePicture, - bio: updates.bio, - tenantId: updates.tenantId, - isInstanceOwner: updates.isInstanceOwner, - }, + const adapter = getAdapter() + await adapter.update('User', userId, { + username: updates.username, + email: updates.email, + role: updates.role, + profilePicture: updates.profilePicture, + bio: updates.bio, + tenantId: updates.tenantId, + isInstanceOwner: updates.isInstanceOwner, }) } diff --git a/frontends/nextjs/src/lib/db/workflows/add-workflow.ts b/frontends/nextjs/src/lib/db/workflows/add-workflow.ts index 5fe1a9257..dc103900b 100644 --- a/frontends/nextjs/src/lib/db/workflows/add-workflow.ts +++ b/frontends/nextjs/src/lib/db/workflows/add-workflow.ts @@ -1,18 +1,17 @@ -import { prisma } from '../prisma' -import type { Workflow } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Workflow } from '../../types/level-types' /** * Add a workflow */ export async function addWorkflow(workflow: Workflow): Promise { - await prisma.workflow.create({ - data: { - id: workflow.id, - name: workflow.name, - description: workflow.description, - nodes: JSON.stringify(workflow.nodes), - edges: JSON.stringify(workflow.edges), - enabled: workflow.enabled, - }, + const adapter = getAdapter() + await adapter.create('Workflow', { + id: workflow.id, + name: workflow.name, + description: workflow.description, + nodes: JSON.stringify(workflow.nodes), + edges: JSON.stringify(workflow.edges), + enabled: workflow.enabled, }) } diff --git a/frontends/nextjs/src/lib/db/workflows/delete-workflow.ts b/frontends/nextjs/src/lib/db/workflows/delete-workflow.ts index 1c63ec494..a0e9ec990 100644 --- a/frontends/nextjs/src/lib/db/workflows/delete-workflow.ts +++ b/frontends/nextjs/src/lib/db/workflows/delete-workflow.ts @@ -1,8 +1,9 @@ -import { prisma } from '../prisma' +import { getAdapter } from '../dbal-client' /** * Delete a workflow by ID */ export async function deleteWorkflow(workflowId: string): Promise { - await prisma.workflow.delete({ where: { id: workflowId } }) + const adapter = getAdapter() + await adapter.delete('Workflow', workflowId) } diff --git a/frontends/nextjs/src/lib/db/workflows/get-workflows.ts b/frontends/nextjs/src/lib/db/workflows/get-workflows.ts index ec8aa5f73..7fc090217 100644 --- a/frontends/nextjs/src/lib/db/workflows/get-workflows.ts +++ b/frontends/nextjs/src/lib/db/workflows/get-workflows.ts @@ -1,12 +1,13 @@ -import { prisma } from '../prisma' -import type { Workflow } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Workflow } from '../../types/level-types' /** * Get all workflows */ export async function getWorkflows(): Promise { - const workflows = await prisma.workflow.findMany() - return workflows.map((w) => ({ + const adapter = getAdapter() + const result = await adapter.list('Workflow') + return (result.data as any[]).map((w) => ({ id: w.id, name: w.name, description: w.description || undefined, diff --git a/frontends/nextjs/src/lib/db/workflows/set-workflows.ts b/frontends/nextjs/src/lib/db/workflows/set-workflows.ts index c4e41706c..5782e76c6 100644 --- a/frontends/nextjs/src/lib/db/workflows/set-workflows.ts +++ b/frontends/nextjs/src/lib/db/workflows/set-workflows.ts @@ -1,21 +1,27 @@ -import { prisma } from '../prisma' -import type { Workflow } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Workflow } from '../../types/level-types' /** * Set all workflows (replaces existing) */ export async function setWorkflows(workflows: Workflow[]): Promise { - await prisma.workflow.deleteMany() + const adapter = getAdapter() + + // Delete existing workflows + const existing = await adapter.list('Workflow') + for (const w of existing.data as any[]) { + await adapter.delete('Workflow', w.id) + } + + // Create new workflows for (const workflow of workflows) { - await prisma.workflow.create({ - data: { - id: workflow.id, - name: workflow.name, - description: workflow.description, - nodes: JSON.stringify(workflow.nodes), - edges: JSON.stringify(workflow.edges), - enabled: workflow.enabled, - }, + await adapter.create('Workflow', { + id: workflow.id, + name: workflow.name, + description: workflow.description, + nodes: JSON.stringify(workflow.nodes), + edges: JSON.stringify(workflow.edges), + enabled: workflow.enabled, }) } } diff --git a/frontends/nextjs/src/lib/db/workflows/update-workflow.ts b/frontends/nextjs/src/lib/db/workflows/update-workflow.ts index cade461ae..0140627cd 100644 --- a/frontends/nextjs/src/lib/db/workflows/update-workflow.ts +++ b/frontends/nextjs/src/lib/db/workflows/update-workflow.ts @@ -1,19 +1,17 @@ -import { prisma } from '../prisma' -import type { Workflow } from '../../level-types' +import { getAdapter } from '../dbal-client' +import type { Workflow } from '../../types/level-types' /** * Update a workflow by ID */ export async function updateWorkflow(workflowId: string, updates: Partial): Promise { - const data: any = {} + const adapter = getAdapter() + const data: Record = {} if (updates.name !== undefined) data.name = updates.name if (updates.description !== undefined) data.description = updates.description if (updates.nodes !== undefined) data.nodes = JSON.stringify(updates.nodes) if (updates.edges !== undefined) data.edges = JSON.stringify(updates.edges) if (updates.enabled !== undefined) data.enabled = updates.enabled - await prisma.workflow.update({ - where: { id: workflowId }, - data, - }) + await adapter.update('Workflow', workflowId, data) } diff --git a/frontends/nextjs/src/lib/database-dbal.server.ts b/frontends/nextjs/src/lib/dbal/database-dbal.server.ts similarity index 98% rename from frontends/nextjs/src/lib/database-dbal.server.ts rename to frontends/nextjs/src/lib/dbal/database-dbal.server.ts index d5f0c0e78..d601d6fff 100644 --- a/frontends/nextjs/src/lib/database-dbal.server.ts +++ b/frontends/nextjs/src/lib/dbal/database-dbal.server.ts @@ -7,7 +7,7 @@ import 'server-only' import { DBALClient } from '@/lib/dbal-stub' import type { DBALConfig } from '@/lib/dbal-stub' -import type { User } from './level-types' +import type { User } from '../types/level-types' let dbalClient: DBALClient | null = null let initialized = false diff --git a/frontends/nextjs/src/lib/dbal-client.ts b/frontends/nextjs/src/lib/dbal/dbal-client.ts similarity index 95% rename from frontends/nextjs/src/lib/dbal-client.ts rename to frontends/nextjs/src/lib/dbal/dbal-client.ts index 70c26ea41..cabd06b32 100644 --- a/frontends/nextjs/src/lib/dbal-client.ts +++ b/frontends/nextjs/src/lib/dbal/dbal-client.ts @@ -1,6 +1,6 @@ import { DBALClient } from '@/lib/dbal-stub' import type { DBALConfig } from '@/lib/dbal-stub' -import type { User } from './level-types' +import type { User } from '../types/level-types' let dbalInstance: DBALClient | null = null diff --git a/frontends/nextjs/src/lib/dbal-integration.ts b/frontends/nextjs/src/lib/dbal/dbal-integration.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-integration.ts rename to frontends/nextjs/src/lib/dbal/dbal-integration.ts diff --git a/frontends/nextjs/src/lib/dbal-stub.ts b/frontends/nextjs/src/lib/dbal/dbal-stub.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/blob/index.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/blob/index.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/blob/index.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/blob/index.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/blob/tenant-aware-storage.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/blob/tenant-aware-storage.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/blob/tenant-aware-storage.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/blob/tenant-aware-storage.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/core/kv-store.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/core/kv-store.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/core/tenant-context.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/core/tenant-context.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/core/types.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/core/types.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/core/types.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/core/types.ts diff --git a/frontends/nextjs/src/lib/dbal-stub/index.ts b/frontends/nextjs/src/lib/dbal/dbal-stub/index.ts similarity index 100% rename from frontends/nextjs/src/lib/dbal-stub/index.ts rename to frontends/nextjs/src/lib/dbal/dbal-stub/index.ts diff --git a/frontends/nextjs/src/lib/dbal/index.ts b/frontends/nextjs/src/lib/dbal/index.ts new file mode 100644 index 000000000..e1686bd58 --- /dev/null +++ b/frontends/nextjs/src/lib/dbal/index.ts @@ -0,0 +1,4 @@ +// DBAL (Database Abstraction Layer) exports +export { DBALClient, createDBALClient } from './dbal-client' +export { getDBALIntegration, initializeDBAL } from './dbal-integration' +export { createDBALStub, DBALStub } from './dbal-stub' diff --git a/frontends/nextjs/src/lib/index.ts b/frontends/nextjs/src/lib/index.ts new file mode 100644 index 000000000..b37901319 --- /dev/null +++ b/frontends/nextjs/src/lib/index.ts @@ -0,0 +1,51 @@ +/** + * Library exports - Centralized re-exports for all lib modules + * + * This file provides a clean API for importing from @/lib + * Instead of: import { User } from '@/lib/types/level-types' + * Use: import { User } from '@/lib' + */ + +// Types +export * from './types' + +// Core utilities +export * from './utils' +export { prisma } from './prisma' + +// Authentication +export * from './auth' + +// Database +export { Database } from './database' +export * from './db' + +// DBAL +export * from './dbal' + +// Schema utilities +export * from './schema' + +// Security +export * from './security' + +// Lua engine +export * from './lua' + +// Components +export * from './components' + +// Packages +export * from './packages' + +// Rendering +export * from './rendering' + +// Seed data +export * from './seed' + +// Workflow +export * from './workflow' + +// Password utilities +export * from './password' diff --git a/frontends/nextjs/src/lib/lua/index.ts b/frontends/nextjs/src/lib/lua/index.ts new file mode 100644 index 000000000..8bf434b19 --- /dev/null +++ b/frontends/nextjs/src/lib/lua/index.ts @@ -0,0 +1,5 @@ +// Lua engine exports +export { LuaEngine } from './lua-engine' +export { SandboxedLuaEngine } from './sandboxed-lua-engine' +export { luaSnippets } from './lua-snippets' +export { luaExamples } from './lua-examples' diff --git a/frontends/nextjs/src/lib/lua-engine.test.ts b/frontends/nextjs/src/lib/lua/lua-engine.test.ts similarity index 100% rename from frontends/nextjs/src/lib/lua-engine.test.ts rename to frontends/nextjs/src/lib/lua/lua-engine.test.ts diff --git a/frontends/nextjs/src/lib/lua-engine.ts b/frontends/nextjs/src/lib/lua/lua-engine.ts similarity index 100% rename from frontends/nextjs/src/lib/lua-engine.ts rename to frontends/nextjs/src/lib/lua/lua-engine.ts diff --git a/frontends/nextjs/src/lib/lua-examples.ts b/frontends/nextjs/src/lib/lua/lua-examples.ts similarity index 100% rename from frontends/nextjs/src/lib/lua-examples.ts rename to frontends/nextjs/src/lib/lua/lua-examples.ts diff --git a/frontends/nextjs/src/lib/lua-snippets.ts b/frontends/nextjs/src/lib/lua/lua-snippets.ts similarity index 100% rename from frontends/nextjs/src/lib/lua-snippets.ts rename to frontends/nextjs/src/lib/lua/lua-snippets.ts diff --git a/frontends/nextjs/src/lib/sandboxed-lua-engine.ts b/frontends/nextjs/src/lib/lua/sandboxed-lua-engine.ts similarity index 100% rename from frontends/nextjs/src/lib/sandboxed-lua-engine.ts rename to frontends/nextjs/src/lib/lua/sandboxed-lua-engine.ts diff --git a/frontends/nextjs/src/lib/packages/index.ts b/frontends/nextjs/src/lib/packages/index.ts new file mode 100644 index 000000000..de8aa09c6 --- /dev/null +++ b/frontends/nextjs/src/lib/packages/index.ts @@ -0,0 +1,6 @@ +// Package system exports +export * from './package-types' +export { initializePackageSystem, buildPackageRegistry } from './package-loader' +export { exportAllPackagesForSeed } from './package-export' +export { packageCatalog } from './package-catalog' +export { packageGlue, getPackageGlue } from './package-glue' diff --git a/frontends/nextjs/src/lib/package-loader/get-installed-package-ids.ts b/frontends/nextjs/src/lib/packages/loader/get-installed-package-ids.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-installed-package-ids.ts rename to frontends/nextjs/src/lib/packages/loader/get-installed-package-ids.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-modular-package-components.ts b/frontends/nextjs/src/lib/packages/loader/get-modular-package-components.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-modular-package-components.ts rename to frontends/nextjs/src/lib/packages/loader/get-modular-package-components.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-modular-package-metadata.ts b/frontends/nextjs/src/lib/packages/loader/get-modular-package-metadata.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-modular-package-metadata.ts rename to frontends/nextjs/src/lib/packages/loader/get-modular-package-metadata.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-modular-package-scripts.ts b/frontends/nextjs/src/lib/packages/loader/get-modular-package-scripts.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-modular-package-scripts.ts rename to frontends/nextjs/src/lib/packages/loader/get-modular-package-scripts.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-package-content.ts b/frontends/nextjs/src/lib/packages/loader/get-package-content.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-package-content.ts rename to frontends/nextjs/src/lib/packages/loader/get-package-content.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-package-manifest.ts b/frontends/nextjs/src/lib/packages/loader/get-package-manifest.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-package-manifest.ts rename to frontends/nextjs/src/lib/packages/loader/get-package-manifest.ts diff --git a/frontends/nextjs/src/lib/package-loader/get-package-registry.ts b/frontends/nextjs/src/lib/packages/loader/get-package-registry.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/get-package-registry.ts rename to frontends/nextjs/src/lib/packages/loader/get-package-registry.ts diff --git a/frontends/nextjs/src/lib/package-loader/index.ts b/frontends/nextjs/src/lib/packages/loader/index.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/index.ts rename to frontends/nextjs/src/lib/packages/loader/index.ts diff --git a/frontends/nextjs/src/lib/package-loader/initialize-package-system.ts b/frontends/nextjs/src/lib/packages/loader/initialize-package-system.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/initialize-package-system.ts rename to frontends/nextjs/src/lib/packages/loader/initialize-package-system.ts diff --git a/frontends/nextjs/src/lib/package-loader/modular-package-seed-data.ts b/frontends/nextjs/src/lib/packages/loader/modular-package-seed-data.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader/modular-package-seed-data.ts rename to frontends/nextjs/src/lib/packages/loader/modular-package-seed-data.ts diff --git a/frontends/nextjs/src/lib/package-catalog.ts b/frontends/nextjs/src/lib/packages/package-catalog.ts similarity index 100% rename from frontends/nextjs/src/lib/package-catalog.ts rename to frontends/nextjs/src/lib/packages/package-catalog.ts diff --git a/frontends/nextjs/src/lib/package-export.ts b/frontends/nextjs/src/lib/packages/package-export.ts similarity index 100% rename from frontends/nextjs/src/lib/package-export.ts rename to frontends/nextjs/src/lib/packages/package-export.ts diff --git a/frontends/nextjs/src/lib/package-glue.test.ts b/frontends/nextjs/src/lib/packages/package-glue.test.ts similarity index 100% rename from frontends/nextjs/src/lib/package-glue.test.ts rename to frontends/nextjs/src/lib/packages/package-glue.test.ts diff --git a/frontends/nextjs/src/lib/package-glue.ts b/frontends/nextjs/src/lib/packages/package-glue.ts similarity index 100% rename from frontends/nextjs/src/lib/package-glue.ts rename to frontends/nextjs/src/lib/packages/package-glue.ts diff --git a/frontends/nextjs/src/lib/package-loader.test.ts b/frontends/nextjs/src/lib/packages/package-loader.test.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader.test.ts rename to frontends/nextjs/src/lib/packages/package-loader.test.ts diff --git a/frontends/nextjs/src/lib/package-loader.ts b/frontends/nextjs/src/lib/packages/package-loader.ts similarity index 100% rename from frontends/nextjs/src/lib/package-loader.ts rename to frontends/nextjs/src/lib/packages/package-loader.ts diff --git a/frontends/nextjs/src/lib/package-types.ts b/frontends/nextjs/src/lib/packages/package-types.ts similarity index 100% rename from frontends/nextjs/src/lib/package-types.ts rename to frontends/nextjs/src/lib/packages/package-types.ts diff --git a/frontends/nextjs/src/lib/password-utils.test.ts b/frontends/nextjs/src/lib/password/password-utils.test.ts similarity index 100% rename from frontends/nextjs/src/lib/password-utils.test.ts rename to frontends/nextjs/src/lib/password/password-utils.test.ts diff --git a/frontends/nextjs/src/lib/password-utils.ts b/frontends/nextjs/src/lib/password/password-utils.ts similarity index 100% rename from frontends/nextjs/src/lib/password-utils.ts rename to frontends/nextjs/src/lib/password/password-utils.ts diff --git a/frontends/nextjs/src/lib/declarative-component-renderer.test.ts b/frontends/nextjs/src/lib/rendering/declarative-component-renderer.test.ts similarity index 100% rename from frontends/nextjs/src/lib/declarative-component-renderer.test.ts rename to frontends/nextjs/src/lib/rendering/declarative-component-renderer.test.ts diff --git a/frontends/nextjs/src/lib/declarative-component-renderer.ts b/frontends/nextjs/src/lib/rendering/declarative-component-renderer.ts similarity index 100% rename from frontends/nextjs/src/lib/declarative-component-renderer.ts rename to frontends/nextjs/src/lib/rendering/declarative-component-renderer.ts diff --git a/frontends/nextjs/src/lib/rendering/index.ts b/frontends/nextjs/src/lib/rendering/index.ts new file mode 100644 index 000000000..e1bcda2c4 --- /dev/null +++ b/frontends/nextjs/src/lib/rendering/index.ts @@ -0,0 +1,4 @@ +// Rendering system exports +export { DeclarativeComponentRenderer } from './declarative-component-renderer' +export { PageRenderer, renderPage } from './page-renderer' +export { PageDefinitionBuilder, buildPageDefinition } from './page-definition-builder' diff --git a/frontends/nextjs/src/lib/page-definition-builder.ts b/frontends/nextjs/src/lib/rendering/page-definition-builder.ts similarity index 100% rename from frontends/nextjs/src/lib/page-definition-builder.ts rename to frontends/nextjs/src/lib/rendering/page-definition-builder.ts diff --git a/frontends/nextjs/src/lib/page-renderer.test.ts b/frontends/nextjs/src/lib/rendering/page-renderer.test.ts similarity index 99% rename from frontends/nextjs/src/lib/page-renderer.test.ts rename to frontends/nextjs/src/lib/rendering/page-renderer.test.ts index 3331090d2..227fa4afd 100644 --- a/frontends/nextjs/src/lib/page-renderer.test.ts +++ b/frontends/nextjs/src/lib/rendering/page-renderer.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest' import type { PageDefinition } from './page-renderer' -import type { User } from './level-types' +import type { User } from '../types/level-types' // Mock Database const { Database, MockLuaEngine } = vi.hoisted(() => { diff --git a/frontends/nextjs/src/lib/page-renderer.ts b/frontends/nextjs/src/lib/rendering/page-renderer.ts similarity index 99% rename from frontends/nextjs/src/lib/page-renderer.ts rename to frontends/nextjs/src/lib/rendering/page-renderer.ts index bfb5cdd29..b67e4186e 100644 --- a/frontends/nextjs/src/lib/page-renderer.ts +++ b/frontends/nextjs/src/lib/rendering/page-renderer.ts @@ -1,5 +1,5 @@ import type { ComponentInstance } from './builder-types' -import type { User } from './level-types' +import type { User } from '../types/level-types' import { Database } from './database' import { LuaEngine } from './lua-engine' diff --git a/frontends/nextjs/src/lib/default-schema.ts b/frontends/nextjs/src/lib/schema/default-schema.ts similarity index 99% rename from frontends/nextjs/src/lib/default-schema.ts rename to frontends/nextjs/src/lib/schema/default-schema.ts index 867431c53..398071c44 100644 --- a/frontends/nextjs/src/lib/default-schema.ts +++ b/frontends/nextjs/src/lib/schema/default-schema.ts @@ -1,4 +1,4 @@ -import type { SchemaConfig } from './schema-types' +import type { SchemaConfig } from '../types/schema-types' export const defaultSchema: SchemaConfig = { apps: [ diff --git a/frontends/nextjs/src/lib/schema/index.ts b/frontends/nextjs/src/lib/schema/index.ts new file mode 100644 index 000000000..f248cfa7b --- /dev/null +++ b/frontends/nextjs/src/lib/schema/index.ts @@ -0,0 +1,3 @@ +// Schema utilities exports +export * from './schema-utils' +export { defaultSchema, getDefaultSchema } from './default-schema' diff --git a/frontends/nextjs/src/lib/schema-utils.test.ts b/frontends/nextjs/src/lib/schema/schema-utils.test.ts similarity index 100% rename from frontends/nextjs/src/lib/schema-utils.test.ts rename to frontends/nextjs/src/lib/schema/schema-utils.test.ts diff --git a/frontends/nextjs/src/lib/schema-utils.ts b/frontends/nextjs/src/lib/schema/schema-utils.ts similarity index 98% rename from frontends/nextjs/src/lib/schema-utils.ts rename to frontends/nextjs/src/lib/schema/schema-utils.ts index 622f94e49..3cabd9ffb 100644 --- a/frontends/nextjs/src/lib/schema-utils.ts +++ b/frontends/nextjs/src/lib/schema/schema-utils.ts @@ -1,4 +1,4 @@ -import type { FieldSchema, ModelSchema, SchemaConfig } from './schema-types' +import type { FieldSchema, ModelSchema, SchemaConfig } from './types/schema-types' export function getModelKey(appName: string, modelName: string): string { return `${appName}_${modelName}` diff --git a/frontends/nextjs/src/lib/security/index.ts b/frontends/nextjs/src/lib/security/index.ts new file mode 100644 index 000000000..995fecf9f --- /dev/null +++ b/frontends/nextjs/src/lib/security/index.ts @@ -0,0 +1,3 @@ +// Security utilities exports +export { SecurityScanner, scanForVulnerabilities } from './security-scanner' +export { SecureDBLayer, createSecureDBLayer } from './secure-db-layer' diff --git a/frontends/nextjs/src/lib/secure-db-layer.ts b/frontends/nextjs/src/lib/security/secure-db-layer.ts similarity index 99% rename from frontends/nextjs/src/lib/secure-db-layer.ts rename to frontends/nextjs/src/lib/security/secure-db-layer.ts index 1637b813b..94c8504ac 100644 --- a/frontends/nextjs/src/lib/secure-db-layer.ts +++ b/frontends/nextjs/src/lib/security/secure-db-layer.ts @@ -1,5 +1,5 @@ import { prisma } from './prisma' -import type { User } from './level-types' +import type { User } from '../types/level-types' export type OperationType = 'CREATE' | 'READ' | 'UPDATE' | 'DELETE' export type ResourceType = 'user' | 'workflow' | 'luaScript' | 'pageConfig' | diff --git a/frontends/nextjs/src/lib/security-scanner.test.ts b/frontends/nextjs/src/lib/security/security-scanner.test.ts similarity index 100% rename from frontends/nextjs/src/lib/security-scanner.test.ts rename to frontends/nextjs/src/lib/security/security-scanner.test.ts diff --git a/frontends/nextjs/src/lib/security-scanner.ts b/frontends/nextjs/src/lib/security/security-scanner.ts similarity index 100% rename from frontends/nextjs/src/lib/security-scanner.ts rename to frontends/nextjs/src/lib/security/security-scanner.ts diff --git a/frontends/nextjs/src/lib/seed/index.ts b/frontends/nextjs/src/lib/seed/index.ts new file mode 100644 index 000000000..f99a87598 --- /dev/null +++ b/frontends/nextjs/src/lib/seed/index.ts @@ -0,0 +1,2 @@ +// Seed data exports +export { seedDatabase, getSeedData } from './seed-data' diff --git a/frontends/nextjs/src/lib/seed-data.test.ts b/frontends/nextjs/src/lib/seed/seed-data.test.ts similarity index 100% rename from frontends/nextjs/src/lib/seed-data.test.ts rename to frontends/nextjs/src/lib/seed/seed-data.test.ts diff --git a/frontends/nextjs/src/lib/seed-data.ts b/frontends/nextjs/src/lib/seed/seed-data.ts similarity index 100% rename from frontends/nextjs/src/lib/seed-data.ts rename to frontends/nextjs/src/lib/seed/seed-data.ts diff --git a/frontends/nextjs/src/lib/builder-types.ts b/frontends/nextjs/src/lib/types/builder-types.ts similarity index 100% rename from frontends/nextjs/src/lib/builder-types.ts rename to frontends/nextjs/src/lib/types/builder-types.ts diff --git a/frontends/nextjs/src/lib/types/index.ts b/frontends/nextjs/src/lib/types/index.ts new file mode 100644 index 000000000..a7947cdfd --- /dev/null +++ b/frontends/nextjs/src/lib/types/index.ts @@ -0,0 +1,4 @@ +// Type definitions +export * from '../types/level-types' +export * from './types/schema-types' +export * from './builder-types' diff --git a/frontends/nextjs/src/lib/level-types.ts b/frontends/nextjs/src/lib/types/level-types.ts similarity index 100% rename from frontends/nextjs/src/lib/level-types.ts rename to frontends/nextjs/src/lib/types/level-types.ts diff --git a/frontends/nextjs/src/lib/schema-types.ts b/frontends/nextjs/src/lib/types/schema-types.ts similarity index 100% rename from frontends/nextjs/src/lib/schema-types.ts rename to frontends/nextjs/src/lib/types/schema-types.ts diff --git a/frontends/nextjs/src/lib/workflow/execute-action-node.ts b/frontends/nextjs/src/lib/workflow/execute-action-node.ts index 0e1573034..72188d578 100644 --- a/frontends/nextjs/src/lib/workflow/execute-action-node.ts +++ b/frontends/nextjs/src/lib/workflow/execute-action-node.ts @@ -1,4 +1,4 @@ -import type { WorkflowNode } from '../level-types' +import type { WorkflowNode } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { logToWorkflow } from './log-to-workflow' diff --git a/frontends/nextjs/src/lib/workflow/execute-condition-node.ts b/frontends/nextjs/src/lib/workflow/execute-condition-node.ts index 7faf57af8..8e93d8304 100644 --- a/frontends/nextjs/src/lib/workflow/execute-condition-node.ts +++ b/frontends/nextjs/src/lib/workflow/execute-condition-node.ts @@ -1,4 +1,4 @@ -import type { WorkflowNode } from '../level-types' +import type { WorkflowNode } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { logToWorkflow } from './log-to-workflow' diff --git a/frontends/nextjs/src/lib/workflow/execute-lua-code.ts b/frontends/nextjs/src/lib/workflow/execute-lua-code.ts index ce094a089..a0d8ba18f 100644 --- a/frontends/nextjs/src/lib/workflow/execute-lua-code.ts +++ b/frontends/nextjs/src/lib/workflow/execute-lua-code.ts @@ -1,4 +1,4 @@ -import { createSandboxedLuaEngine, type SandboxedLuaResult } from '../sandboxed-lua-engine' +import { createSandboxedLuaEngine, type SandboxedLuaResult } from '../lua/sandboxed-lua-engine' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { logToWorkflow } from './log-to-workflow' diff --git a/frontends/nextjs/src/lib/workflow/execute-lua-node.ts b/frontends/nextjs/src/lib/workflow/execute-lua-node.ts index 1cf5f2922..a98c6763a 100644 --- a/frontends/nextjs/src/lib/workflow/execute-lua-node.ts +++ b/frontends/nextjs/src/lib/workflow/execute-lua-node.ts @@ -1,4 +1,4 @@ -import type { WorkflowNode } from '../level-types' +import type { WorkflowNode } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { executeLuaCode } from './execute-lua-code' diff --git a/frontends/nextjs/src/lib/workflow/execute-node.ts b/frontends/nextjs/src/lib/workflow/execute-node.ts index 4523eb4f6..eea2d4a2e 100644 --- a/frontends/nextjs/src/lib/workflow/execute-node.ts +++ b/frontends/nextjs/src/lib/workflow/execute-node.ts @@ -1,4 +1,4 @@ -import type { WorkflowNode } from '../level-types' +import type { WorkflowNode } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { executeActionNode } from './execute-action-node' diff --git a/frontends/nextjs/src/lib/workflow/execute-transform-node.ts b/frontends/nextjs/src/lib/workflow/execute-transform-node.ts index 82b49fb7d..2dbd8ffb7 100644 --- a/frontends/nextjs/src/lib/workflow/execute-transform-node.ts +++ b/frontends/nextjs/src/lib/workflow/execute-transform-node.ts @@ -1,4 +1,4 @@ -import type { WorkflowNode } from '../level-types' +import type { WorkflowNode } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowState } from './workflow-state' import { logToWorkflow } from './log-to-workflow' diff --git a/frontends/nextjs/src/lib/workflow/execute-workflow.ts b/frontends/nextjs/src/lib/workflow/execute-workflow.ts index 4253a188e..c58db064f 100644 --- a/frontends/nextjs/src/lib/workflow/execute-workflow.ts +++ b/frontends/nextjs/src/lib/workflow/execute-workflow.ts @@ -1,4 +1,4 @@ -import type { Workflow } from '../level-types' +import type { Workflow } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowExecutionResult } from './workflow-execution-result' import { createWorkflowState } from './workflow-state' diff --git a/frontends/nextjs/src/lib/workflow/workflow-engine-class.ts b/frontends/nextjs/src/lib/workflow/workflow-engine-class.ts index c0e14c7de..e80952841 100644 --- a/frontends/nextjs/src/lib/workflow/workflow-engine-class.ts +++ b/frontends/nextjs/src/lib/workflow/workflow-engine-class.ts @@ -1,4 +1,4 @@ -import type { Workflow } from '../level-types' +import type { Workflow } from '../types/level-types' import type { WorkflowExecutionContext } from './workflow-execution-context' import type { WorkflowExecutionResult } from './workflow-execution-result' import type { WorkflowState } from './workflow-state' diff --git a/frontends/nextjs/src/lib/workflow-engine.test.ts b/frontends/nextjs/src/lib/workflow/workflow-engine.test.ts similarity index 99% rename from frontends/nextjs/src/lib/workflow-engine.test.ts rename to frontends/nextjs/src/lib/workflow/workflow-engine.test.ts index 5ca766354..6213de05a 100644 --- a/frontends/nextjs/src/lib/workflow-engine.test.ts +++ b/frontends/nextjs/src/lib/workflow/workflow-engine.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest' import { WorkflowEngine, createWorkflowEngine } from './workflow-engine' -import type { Workflow, WorkflowNode, LuaScript } from './level-types' +import type { Workflow, WorkflowNode, LuaScript } from '../types/level-types' // Helper to create a minimal valid WorkflowNode function createNode( diff --git a/frontends/nextjs/src/lib/workflow-engine.ts b/frontends/nextjs/src/lib/workflow/workflow-engine.ts similarity index 100% rename from frontends/nextjs/src/lib/workflow-engine.ts rename to frontends/nextjs/src/lib/workflow/workflow-engine.ts diff --git a/frontends/nextjs/src/lib/workflow/workflow-execution-context.ts b/frontends/nextjs/src/lib/workflow/workflow-execution-context.ts index eda234173..2c7877e28 100644 --- a/frontends/nextjs/src/lib/workflow/workflow-execution-context.ts +++ b/frontends/nextjs/src/lib/workflow/workflow-execution-context.ts @@ -1,4 +1,4 @@ -import type { LuaScript } from '../level-types' +import type { LuaScript } from '../types/level-types' /** * Context passed to workflow execution diff --git a/frontends/nextjs/src/theme/mui-theme.ts b/frontends/nextjs/src/theme/mui-theme.ts new file mode 100644 index 000000000..621911207 --- /dev/null +++ b/frontends/nextjs/src/theme/mui-theme.ts @@ -0,0 +1,8 @@ +'use client' + +// Re-export from modular theme files +export { lightTheme } from './light-theme' +export { darkTheme } from './dark-theme' +export { colors } from './colors' +export { fonts } from './fonts' +export { layout } from './layout' diff --git a/frontends/nextjs/src/theme/tokens.ts b/frontends/nextjs/src/theme/tokens.ts new file mode 100644 index 000000000..f81ca55c1 --- /dev/null +++ b/frontends/nextjs/src/theme/tokens.ts @@ -0,0 +1,4 @@ +// Design tokens - consolidated exports for theme system +export { colors } from './colors' +export { fonts } from './fonts' +export { layout } from './layout'