mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 22:04:56 +00:00
Create missing type definitions and stub implementations
- Created src/lib/types/ directory with level-types.ts and schema-types.ts - Created missing hook implementations (use-mobile, useAutoRefresh, useCodeEditor, useDBAL, useFileTree, useGitHubFetcher, useKV) - Created missing auth API modules (fetch-session, login, logout, register) - Fixed import paths from relative '../../types/*' to '@/lib/*' aliases - Updated AppConfiguration type to match Prisma schema - Reduced TypeScript errors from 346 to 305 Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
20
frontends/nextjs/src/hooks/use-mobile.ts
Normal file
20
frontends/nextjs/src/hooks/use-mobile.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Hook for detecting mobile viewport
|
||||
*/
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export function useIsMobile(): boolean {
|
||||
const [isMobile, setIsMobile] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth < 768)
|
||||
}
|
||||
|
||||
checkMobile()
|
||||
window.addEventListener('resize', checkMobile)
|
||||
return () => window.removeEventListener('resize', checkMobile)
|
||||
}, [])
|
||||
|
||||
return isMobile
|
||||
}
|
||||
13
frontends/nextjs/src/hooks/useAutoRefresh.ts
Normal file
13
frontends/nextjs/src/hooks/useAutoRefresh.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Hook for auto-refreshing data at intervals
|
||||
*/
|
||||
import { useEffect, useCallback } from 'react'
|
||||
|
||||
export function useAutoRefresh(callback: () => void, interval: number = 5000): void {
|
||||
const stableCallback = useCallback(callback, [callback])
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(stableCallback, interval)
|
||||
return () => clearInterval(id)
|
||||
}, [stableCallback, interval])
|
||||
}
|
||||
55
frontends/nextjs/src/hooks/useCodeEditor.ts
Normal file
55
frontends/nextjs/src/hooks/useCodeEditor.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Hook for managing code editor state
|
||||
*/
|
||||
import { useState } from 'react'
|
||||
|
||||
export interface EditorFile {
|
||||
path: string
|
||||
content: string
|
||||
language?: string
|
||||
}
|
||||
|
||||
export interface UseCodeEditorReturn {
|
||||
files: EditorFile[]
|
||||
currentFile: EditorFile | null
|
||||
setCurrentFile: (file: EditorFile | null) => void
|
||||
updateFile: (path: string, content: string) => void
|
||||
addFile: (file: EditorFile) => void
|
||||
removeFile: (path: string) => void
|
||||
}
|
||||
|
||||
export function useCodeEditor(initialFiles: EditorFile[] = []): UseCodeEditorReturn {
|
||||
const [files, setFiles] = useState<EditorFile[]>(initialFiles)
|
||||
const [currentFile, setCurrentFile] = useState<EditorFile | null>(
|
||||
initialFiles.length > 0 ? initialFiles[0] : null
|
||||
)
|
||||
|
||||
const updateFile = (path: string, content: string) => {
|
||||
setFiles(prev =>
|
||||
prev.map(f => (f.path === path ? { ...f, content } : f))
|
||||
)
|
||||
if (currentFile?.path === path) {
|
||||
setCurrentFile({ ...currentFile, content })
|
||||
}
|
||||
}
|
||||
|
||||
const addFile = (file: EditorFile) => {
|
||||
setFiles(prev => [...prev, file])
|
||||
}
|
||||
|
||||
const removeFile = (path: string) => {
|
||||
setFiles(prev => prev.filter(f => f.path !== path))
|
||||
if (currentFile?.path === path) {
|
||||
setCurrentFile(null)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
files,
|
||||
currentFile,
|
||||
setCurrentFile,
|
||||
updateFile,
|
||||
addFile,
|
||||
removeFile,
|
||||
}
|
||||
}
|
||||
114
frontends/nextjs/src/hooks/useDBAL.ts
Normal file
114
frontends/nextjs/src/hooks/useDBAL.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Hook for DBAL operations
|
||||
*/
|
||||
import { useState, useCallback } from 'react'
|
||||
|
||||
export interface UseDBALReturn {
|
||||
get: (entity: string, id: string) => Promise<unknown>
|
||||
list: (entity: string, filter?: Record<string, unknown>) => Promise<unknown[]>
|
||||
create: (entity: string, data: Record<string, unknown>) => Promise<unknown>
|
||||
update: (entity: string, id: string, data: Record<string, unknown>) => Promise<unknown>
|
||||
delete: (entity: string, id: string) => Promise<void>
|
||||
isLoading: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
export function useDBAL(): UseDBALReturn {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
const get = useCallback(async (entity: string, id: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/v1/${entity}/${id}`)
|
||||
if (!response.ok) throw new Error('Failed to fetch')
|
||||
return await response.json()
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const list = useCallback(async (entity: string, filter?: Record<string, unknown>) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const queryString = filter ? `?${new URLSearchParams(filter as Record<string, string>).toString()}` : ''
|
||||
const response = await fetch(`/api/v1/${entity}${queryString}`)
|
||||
if (!response.ok) throw new Error('Failed to fetch')
|
||||
return await response.json()
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const create = useCallback(async (entity: string, data: Record<string, unknown>) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/v1/${entity}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
if (!response.ok) throw new Error('Failed to create')
|
||||
return await response.json()
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const update = useCallback(async (entity: string, id: string, data: Record<string, unknown>) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/v1/${entity}/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
if (!response.ok) throw new Error('Failed to update')
|
||||
return await response.json()
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const deleteEntity = useCallback(async (entity: string, id: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/v1/${entity}/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
if (!response.ok) throw new Error('Failed to delete')
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return {
|
||||
get,
|
||||
list,
|
||||
create,
|
||||
update,
|
||||
delete: deleteEntity,
|
||||
isLoading,
|
||||
error,
|
||||
}
|
||||
}
|
||||
52
frontends/nextjs/src/hooks/useFileTree.ts
Normal file
52
frontends/nextjs/src/hooks/useFileTree.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Hook for managing file tree state
|
||||
*/
|
||||
import { useState } from 'react'
|
||||
|
||||
export interface FileNode {
|
||||
path: string
|
||||
name: string
|
||||
type: 'file' | 'directory'
|
||||
children?: FileNode[]
|
||||
content?: string
|
||||
}
|
||||
|
||||
export interface UseFileTreeReturn {
|
||||
tree: FileNode[]
|
||||
expandedPaths: Set<string>
|
||||
selectedPath: string | null
|
||||
toggleExpanded: (path: string) => void
|
||||
selectPath: (path: string) => void
|
||||
setTree: (tree: FileNode[]) => void
|
||||
}
|
||||
|
||||
export function useFileTree(initialTree: FileNode[] = []): UseFileTreeReturn {
|
||||
const [tree, setTree] = useState<FileNode[]>(initialTree)
|
||||
const [expandedPaths, setExpandedPaths] = useState<Set<string>>(new Set())
|
||||
const [selectedPath, setSelectedPath] = useState<string | null>(null)
|
||||
|
||||
const toggleExpanded = (path: string) => {
|
||||
setExpandedPaths(prev => {
|
||||
const next = new Set(prev)
|
||||
if (next.has(path)) {
|
||||
next.delete(path)
|
||||
} else {
|
||||
next.add(path)
|
||||
}
|
||||
return next
|
||||
})
|
||||
}
|
||||
|
||||
const selectPath = (path: string) => {
|
||||
setSelectedPath(path)
|
||||
}
|
||||
|
||||
return {
|
||||
tree,
|
||||
expandedPaths,
|
||||
selectedPath,
|
||||
toggleExpanded,
|
||||
selectPath,
|
||||
setTree,
|
||||
}
|
||||
}
|
||||
66
frontends/nextjs/src/hooks/useGitHubFetcher.ts
Normal file
66
frontends/nextjs/src/hooks/useGitHubFetcher.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Hook for fetching GitHub Actions workflow data
|
||||
*/
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export interface WorkflowRun {
|
||||
id: number
|
||||
name: string
|
||||
status: string
|
||||
conclusion: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
html_url: string
|
||||
}
|
||||
|
||||
export interface UseGitHubFetcherReturn {
|
||||
runs: WorkflowRun[]
|
||||
isLoading: boolean
|
||||
error: Error | null
|
||||
refresh: () => Promise<void>
|
||||
}
|
||||
|
||||
export function useGitHubFetcher(
|
||||
owner?: string,
|
||||
repo?: string,
|
||||
autoRefresh = false
|
||||
): UseGitHubFetcherReturn {
|
||||
const [runs, setRuns] = useState<WorkflowRun[]>([])
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
const fetchRuns = async () => {
|
||||
if (!owner || !repo) return
|
||||
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/github/actions/runs?owner=${owner}&repo=${repo}`)
|
||||
if (!response.ok) throw new Error('Failed to fetch workflow runs')
|
||||
const data = await response.json()
|
||||
setRuns(data.workflow_runs || [])
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchRuns()
|
||||
}, [owner, repo])
|
||||
|
||||
useEffect(() => {
|
||||
if (autoRefresh) {
|
||||
const interval = setInterval(fetchRuns, 30000)
|
||||
return () => clearInterval(interval)
|
||||
}
|
||||
}, [autoRefresh, owner, repo])
|
||||
|
||||
return {
|
||||
runs,
|
||||
isLoading,
|
||||
error,
|
||||
refresh: fetchRuns,
|
||||
}
|
||||
}
|
||||
97
frontends/nextjs/src/hooks/useKV.ts
Normal file
97
frontends/nextjs/src/hooks/useKV.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Hook for key-value storage operations
|
||||
*/
|
||||
import { useState, useCallback } from 'react'
|
||||
|
||||
export interface UseKVReturn {
|
||||
get: (key: string) => Promise<string | null>
|
||||
set: (key: string, value: string) => Promise<void>
|
||||
delete: (key: string) => Promise<void>
|
||||
list: (prefix?: string) => Promise<string[]>
|
||||
isLoading: boolean
|
||||
error: Error | null
|
||||
}
|
||||
|
||||
export function useKV(): UseKVReturn {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [error, setError] = useState<Error | null>(null)
|
||||
|
||||
const get = useCallback(async (key: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/kv/${key}`)
|
||||
if (!response.ok) {
|
||||
if (response.status === 404) return null
|
||||
throw new Error('Failed to get key')
|
||||
}
|
||||
const data = await response.json()
|
||||
return data.value
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const set = useCallback(async (key: string, value: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/kv/${key}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ value }),
|
||||
})
|
||||
if (!response.ok) throw new Error('Failed to set key')
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const deleteKey = useCallback(async (key: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await fetch(`/api/kv/${key}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
if (!response.ok) throw new Error('Failed to delete key')
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const list = useCallback(async (prefix?: string) => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const queryString = prefix ? `?prefix=${encodeURIComponent(prefix)}` : ''
|
||||
const response = await fetch(`/api/kv${queryString}`)
|
||||
if (!response.ok) throw new Error('Failed to list keys')
|
||||
const data = await response.json()
|
||||
return data.keys || []
|
||||
} catch (err) {
|
||||
setError(err as Error)
|
||||
throw err
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
delete: deleteKey,
|
||||
list,
|
||||
isLoading,
|
||||
error,
|
||||
}
|
||||
}
|
||||
27
frontends/nextjs/src/lib/auth/api/fetch-session.ts
Normal file
27
frontends/nextjs/src/lib/auth/api/fetch-session.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file fetch-session.ts
|
||||
* @description Fetch current user session
|
||||
*/
|
||||
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
export async function fetchSession(): Promise<User | null> {
|
||||
try {
|
||||
const response = await fetch('/api/auth/session', {
|
||||
credentials: 'include',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 401) {
|
||||
return null
|
||||
}
|
||||
throw new Error('Failed to fetch session')
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.user || null
|
||||
} catch (error) {
|
||||
console.error('Error fetching session:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
25
frontends/nextjs/src/lib/auth/api/login.ts
Normal file
25
frontends/nextjs/src/lib/auth/api/login.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file login.ts
|
||||
* @description User login API
|
||||
*/
|
||||
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
export async function login(identifier: string, password: string): Promise<User> {
|
||||
const response = await fetch('/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ identifier, password }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({ message: 'Login failed' }))
|
||||
throw new Error(error.message || 'Login failed')
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.user
|
||||
}
|
||||
15
frontends/nextjs/src/lib/auth/api/logout.ts
Normal file
15
frontends/nextjs/src/lib/auth/api/logout.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @file logout.ts
|
||||
* @description User logout API
|
||||
*/
|
||||
|
||||
export async function logout(): Promise<void> {
|
||||
const response = await fetch('/api/auth/logout', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Logout failed')
|
||||
}
|
||||
}
|
||||
25
frontends/nextjs/src/lib/auth/api/register.ts
Normal file
25
frontends/nextjs/src/lib/auth/api/register.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file register.ts
|
||||
* @description User registration API
|
||||
*/
|
||||
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
export async function register(username: string, email: string, password: string): Promise<User> {
|
||||
const response = await fetch('/api/auth/register', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ username, email, password }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({ message: 'Registration failed' }))
|
||||
throw new Error(error.message || 'Registration failed')
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.user
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AppConfiguration } from '../../types/level-types'
|
||||
import type { AppConfiguration } from '@/lib/level-types'
|
||||
import { getAdapter } from '../core/dbal-client'
|
||||
|
||||
export async function getAppConfig(): Promise<AppConfiguration | null> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AppConfiguration } from '../../types/level-types'
|
||||
import type { AppConfiguration } from '@/lib/level-types'
|
||||
import { getAdapter } from '../core/dbal-client'
|
||||
|
||||
export async function setAppConfig(config: AppConfiguration): Promise<void> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import { verifyPassword } from '../../password/verify-password'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { getUserFirstLoginFlag } from '../../users/getters/get-user-first-login-flag'
|
||||
import { mapUserRecord } from '../../users/map-user-record'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { mapUserRecord } from '../../users/map-user-record'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { mapUserRecord } from '../../users/map-user-record'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
const mockCreate = vi.fn()
|
||||
const mockAdapter = { create: mockCreate }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Add a single comment
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
type DBALCommentRecord = {
|
||||
id: string
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
type DBALCommentRecord = {
|
||||
id: string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
const mockUpdate = vi.fn()
|
||||
const mockAdapter = { update: mockUpdate }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Comment } from '../../types/level-types'
|
||||
import type { Comment } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Update a comment by ID
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { PageConfig } from '../../types/level-types'
|
||||
import type { PageConfig } from '@/lib/level-types'
|
||||
|
||||
const mockCreate = vi.fn()
|
||||
const mockAdapter = { create: mockCreate }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { PageConfig } from '../../types/level-types'
|
||||
import type { PageConfig } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Add a page
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { PageConfig, UserRole } from '../../types/level-types'
|
||||
import type { PageConfig, UserRole } from '@/lib/level-types'
|
||||
|
||||
type DBALPageRecord = {
|
||||
id: string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { PageConfig } from '../../types/level-types'
|
||||
import type { PageConfig } from '@/lib/level-types'
|
||||
|
||||
const mockList = vi.fn()
|
||||
const mockDelete = vi.fn()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { PageConfig } from '../../types/level-types'
|
||||
import type { PageConfig } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Set all pages (replaces existing)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { PageConfig } from '../../types/level-types'
|
||||
import type { PageConfig } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Update a page by ID
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { ModelSchema } from '../../types/schema-types'
|
||||
import type { ModelSchema } from '@/lib/schema-types'
|
||||
|
||||
/**
|
||||
* Update a schema by name
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Tenant } from '../../types/level-types'
|
||||
import type { Tenant } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Add a new tenant
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { JsonValue } from '@/types/utility-types'
|
||||
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Tenant } from '../../types/level-types'
|
||||
import type { Tenant } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Get all tenants from database
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Tenant } from '../../types/level-types'
|
||||
import type { Tenant } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Set all tenants (replaces existing)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Tenant } from '../../types/level-types'
|
||||
import type { Tenant } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Update an existing tenant
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Add a single user
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Update a user by ID
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { mapUserRecord } from '../map-user-record'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { mapUserRecord } from '../map-user-record'
|
||||
|
||||
export type GetUsersOptions = { tenantId: string } | { scope: 'all' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Normalize raw DB records into the shared User shape.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { getAdapter } from '../core/dbal-client'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { User } from '@/lib/level-types'
|
||||
import { mapUserRecord } from '../map-user-record'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Add a workflow
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
type DBALWorkflowRecord = {
|
||||
id: string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
const mockList = vi.fn()
|
||||
const mockDelete = vi.fn()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
type DBALWorkflowRecord = {
|
||||
id: string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
const mockUpdate = vi.fn()
|
||||
const mockAdapter = { update: mockUpdate }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getAdapter } from '../../core/dbal-client'
|
||||
import type { Workflow } from '../../types/level-types'
|
||||
import type { Workflow } from '@/lib/level-types'
|
||||
|
||||
/**
|
||||
* Update a workflow by ID
|
||||
|
||||
117
frontends/nextjs/src/lib/types/level-types.ts
Normal file
117
frontends/nextjs/src/lib/types/level-types.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Core type definitions for MetaBuilder
|
||||
* These types correspond to Prisma models and are used throughout the application
|
||||
*/
|
||||
|
||||
// User role/level types
|
||||
export type UserRole = 'public' | 'user' | 'moderator' | 'admin' | 'god' | 'supergod'
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
username: string
|
||||
email: string
|
||||
role: UserRole
|
||||
profilePicture?: string
|
||||
bio?: string
|
||||
createdAt: number
|
||||
tenantId?: string
|
||||
isInstanceOwner: boolean
|
||||
}
|
||||
|
||||
export interface Tenant {
|
||||
id: string
|
||||
name: string
|
||||
slug: string
|
||||
ownerId: string
|
||||
createdAt: number
|
||||
homepageConfig?: string
|
||||
settings?: string
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
id: string
|
||||
tenantId?: string
|
||||
userId: string
|
||||
content: string
|
||||
createdAt: number
|
||||
updatedAt?: number
|
||||
parentId?: string
|
||||
entityType?: string
|
||||
entityId?: string
|
||||
}
|
||||
|
||||
export interface PageConfig {
|
||||
id: string
|
||||
tenantId?: string
|
||||
packageId?: string
|
||||
path: string
|
||||
title: string
|
||||
description?: string
|
||||
icon?: string
|
||||
component?: string
|
||||
componentTree: string
|
||||
level: number
|
||||
requiresAuth: boolean
|
||||
requiredRole?: string
|
||||
parentPath?: string
|
||||
sortOrder: number
|
||||
isPublished: boolean
|
||||
}
|
||||
|
||||
export interface Workflow {
|
||||
id: string
|
||||
tenantId?: string
|
||||
name: string
|
||||
description?: string
|
||||
trigger: string
|
||||
actions: string
|
||||
isActive: boolean
|
||||
createdAt: number
|
||||
updatedAt?: number
|
||||
}
|
||||
|
||||
export interface LuaScript {
|
||||
id: string
|
||||
tenantId?: string
|
||||
name: string
|
||||
description?: string
|
||||
script: string
|
||||
isActive: boolean
|
||||
createdAt: number
|
||||
updatedAt?: number
|
||||
}
|
||||
|
||||
export interface AppConfiguration {
|
||||
id: string
|
||||
name: string
|
||||
schemas: string | unknown[] // JSON string or parsed array
|
||||
workflows: string | unknown[] // JSON string or parsed array
|
||||
luaScripts: string | unknown[] // JSON string or parsed array
|
||||
pages: string | unknown[] // JSON string or parsed array
|
||||
theme: string | unknown // JSON string or parsed object
|
||||
}
|
||||
|
||||
export interface PowerTransferRequest {
|
||||
id: string
|
||||
fromUserId: string
|
||||
toUserId: string
|
||||
status: string
|
||||
requestedAt: number
|
||||
resolvedAt?: number
|
||||
expiresAt?: number
|
||||
}
|
||||
|
||||
// SMTPConfig type
|
||||
export interface SMTPConfig {
|
||||
id: string
|
||||
tenantId?: string
|
||||
host: string
|
||||
port: number
|
||||
username: string
|
||||
password: string
|
||||
fromEmail: string
|
||||
fromName?: string
|
||||
secure: boolean
|
||||
createdAt: number
|
||||
updatedAt?: number
|
||||
}
|
||||
39
frontends/nextjs/src/lib/types/schema-types.ts
Normal file
39
frontends/nextjs/src/lib/types/schema-types.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Schema type definitions for MetaBuilder
|
||||
* These types define the structure of dynamic schemas and models
|
||||
*/
|
||||
|
||||
export interface FieldDefinition {
|
||||
name: string
|
||||
type: string
|
||||
label?: string
|
||||
required?: boolean
|
||||
defaultValue?: unknown
|
||||
validation?: Record<string, unknown>
|
||||
options?: Array<{ value: string; label: string }>
|
||||
}
|
||||
|
||||
export interface ModelSchema {
|
||||
id: string
|
||||
tenantId?: string
|
||||
name: string
|
||||
label?: string
|
||||
labelPlural?: string
|
||||
icon?: string
|
||||
fields: FieldDefinition[] | string // Can be JSON string or parsed array
|
||||
listDisplay?: string[] | string
|
||||
listFilter?: string[] | string
|
||||
searchFields?: string[] | string
|
||||
ordering?: string[] | string
|
||||
validations?: Record<string, unknown> | string
|
||||
hooks?: Record<string, unknown> | string
|
||||
}
|
||||
|
||||
export interface DynamicData {
|
||||
id: string
|
||||
tenantId?: string
|
||||
schemaId: string
|
||||
data: string // JSON data
|
||||
createdAt: number
|
||||
updatedAt?: number
|
||||
}
|
||||
Reference in New Issue
Block a user