From a8236e8783bed5b5a7afbe679fed5b7d56c9f25f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fahri=20Can=20Se=C3=A7er?= Date: Sat, 7 Feb 2026 01:52:31 +0300 Subject: [PATCH] main --- .../agents/frontend-developer.md | 0 .../agents/nextjs-architecture-expert.md | 0 .../commands/nextjs-api-tester.md | 0 .../commands/nextjs-component-generator.md | 0 .../skills/frontend-design/SKILL.md | 0 .../skills/senior-frontend/SKILL.md | 0 .../references/frontend_best_practices.md | 0 .../references/nextjs_optimization_guide.md | 0 .../references/react_patterns.md | 0 .../scripts/bundle_analyzer.py | 0 .../scripts/component_generator.py | 0 .../scripts/frontend_scaffolder.py | 0 {.agent => .claude}/skills/senior-qa/SKILL.md | 0 .../senior-qa/references/qa_best_practices.md | 0 .../references/test_automation_patterns.md | 0 .../references/testing_strategies.md | 0 .../senior-qa/scripts/coverage_analyzer.py | 0 .../senior-qa/scripts/e2e_test_scaffolder.py | 0 .../senior-qa/scripts/test_suite_generator.py | 0 .github/workflows/deploy-ui.yml | 45 ++++++++++++++++ Dockerfile | 46 ++++++++++++++++ next.config.ts | 3 +- package-lock.json | 1 - src/lib/api/ai-writer/service.ts | 16 ------ src/lib/api/ai-writer/types.ts | 15 ------ src/lib/api/ai-writer/use-hooks.ts | 10 ---- src/lib/api/example/index.ts | 2 +- src/lib/api/projects/service.ts | 52 ------------------- src/lib/api/projects/types.ts | 24 --------- src/lib/api/projects/use-hooks.ts | 48 ----------------- 30 files changed, 94 insertions(+), 168 deletions(-) rename {.agent => .claude}/agents/frontend-developer.md (100%) rename {.agent => .claude}/agents/nextjs-architecture-expert.md (100%) rename {.agent => .claude}/commands/nextjs-api-tester.md (100%) rename {.agent => .claude}/commands/nextjs-component-generator.md (100%) rename {.agent => .claude}/skills/frontend-design/SKILL.md (100%) rename {.agent => .claude}/skills/senior-frontend/SKILL.md (100%) rename {.agent => .claude}/skills/senior-frontend/references/frontend_best_practices.md (100%) rename {.agent => .claude}/skills/senior-frontend/references/nextjs_optimization_guide.md (100%) rename {.agent => .claude}/skills/senior-frontend/references/react_patterns.md (100%) rename {.agent => .claude}/skills/senior-frontend/scripts/bundle_analyzer.py (100%) rename {.agent => .claude}/skills/senior-frontend/scripts/component_generator.py (100%) rename {.agent => .claude}/skills/senior-frontend/scripts/frontend_scaffolder.py (100%) rename {.agent => .claude}/skills/senior-qa/SKILL.md (100%) rename {.agent => .claude}/skills/senior-qa/references/qa_best_practices.md (100%) rename {.agent => .claude}/skills/senior-qa/references/test_automation_patterns.md (100%) rename {.agent => .claude}/skills/senior-qa/references/testing_strategies.md (100%) rename {.agent => .claude}/skills/senior-qa/scripts/coverage_analyzer.py (100%) rename {.agent => .claude}/skills/senior-qa/scripts/e2e_test_scaffolder.py (100%) rename {.agent => .claude}/skills/senior-qa/scripts/test_suite_generator.py (100%) create mode 100644 .github/workflows/deploy-ui.yml create mode 100644 Dockerfile delete mode 100644 src/lib/api/ai-writer/service.ts delete mode 100644 src/lib/api/ai-writer/types.ts delete mode 100644 src/lib/api/ai-writer/use-hooks.ts delete mode 100644 src/lib/api/projects/service.ts delete mode 100644 src/lib/api/projects/types.ts delete mode 100644 src/lib/api/projects/use-hooks.ts diff --git a/.agent/agents/frontend-developer.md b/.claude/agents/frontend-developer.md similarity index 100% rename from .agent/agents/frontend-developer.md rename to .claude/agents/frontend-developer.md diff --git a/.agent/agents/nextjs-architecture-expert.md b/.claude/agents/nextjs-architecture-expert.md similarity index 100% rename from .agent/agents/nextjs-architecture-expert.md rename to .claude/agents/nextjs-architecture-expert.md diff --git a/.agent/commands/nextjs-api-tester.md b/.claude/commands/nextjs-api-tester.md similarity index 100% rename from .agent/commands/nextjs-api-tester.md rename to .claude/commands/nextjs-api-tester.md diff --git a/.agent/commands/nextjs-component-generator.md b/.claude/commands/nextjs-component-generator.md similarity index 100% rename from .agent/commands/nextjs-component-generator.md rename to .claude/commands/nextjs-component-generator.md diff --git a/.agent/skills/frontend-design/SKILL.md b/.claude/skills/frontend-design/SKILL.md similarity index 100% rename from .agent/skills/frontend-design/SKILL.md rename to .claude/skills/frontend-design/SKILL.md diff --git a/.agent/skills/senior-frontend/SKILL.md b/.claude/skills/senior-frontend/SKILL.md similarity index 100% rename from .agent/skills/senior-frontend/SKILL.md rename to .claude/skills/senior-frontend/SKILL.md diff --git a/.agent/skills/senior-frontend/references/frontend_best_practices.md b/.claude/skills/senior-frontend/references/frontend_best_practices.md similarity index 100% rename from .agent/skills/senior-frontend/references/frontend_best_practices.md rename to .claude/skills/senior-frontend/references/frontend_best_practices.md diff --git a/.agent/skills/senior-frontend/references/nextjs_optimization_guide.md b/.claude/skills/senior-frontend/references/nextjs_optimization_guide.md similarity index 100% rename from .agent/skills/senior-frontend/references/nextjs_optimization_guide.md rename to .claude/skills/senior-frontend/references/nextjs_optimization_guide.md diff --git a/.agent/skills/senior-frontend/references/react_patterns.md b/.claude/skills/senior-frontend/references/react_patterns.md similarity index 100% rename from .agent/skills/senior-frontend/references/react_patterns.md rename to .claude/skills/senior-frontend/references/react_patterns.md diff --git a/.agent/skills/senior-frontend/scripts/bundle_analyzer.py b/.claude/skills/senior-frontend/scripts/bundle_analyzer.py similarity index 100% rename from .agent/skills/senior-frontend/scripts/bundle_analyzer.py rename to .claude/skills/senior-frontend/scripts/bundle_analyzer.py diff --git a/.agent/skills/senior-frontend/scripts/component_generator.py b/.claude/skills/senior-frontend/scripts/component_generator.py similarity index 100% rename from .agent/skills/senior-frontend/scripts/component_generator.py rename to .claude/skills/senior-frontend/scripts/component_generator.py diff --git a/.agent/skills/senior-frontend/scripts/frontend_scaffolder.py b/.claude/skills/senior-frontend/scripts/frontend_scaffolder.py similarity index 100% rename from .agent/skills/senior-frontend/scripts/frontend_scaffolder.py rename to .claude/skills/senior-frontend/scripts/frontend_scaffolder.py diff --git a/.agent/skills/senior-qa/SKILL.md b/.claude/skills/senior-qa/SKILL.md similarity index 100% rename from .agent/skills/senior-qa/SKILL.md rename to .claude/skills/senior-qa/SKILL.md diff --git a/.agent/skills/senior-qa/references/qa_best_practices.md b/.claude/skills/senior-qa/references/qa_best_practices.md similarity index 100% rename from .agent/skills/senior-qa/references/qa_best_practices.md rename to .claude/skills/senior-qa/references/qa_best_practices.md diff --git a/.agent/skills/senior-qa/references/test_automation_patterns.md b/.claude/skills/senior-qa/references/test_automation_patterns.md similarity index 100% rename from .agent/skills/senior-qa/references/test_automation_patterns.md rename to .claude/skills/senior-qa/references/test_automation_patterns.md diff --git a/.agent/skills/senior-qa/references/testing_strategies.md b/.claude/skills/senior-qa/references/testing_strategies.md similarity index 100% rename from .agent/skills/senior-qa/references/testing_strategies.md rename to .claude/skills/senior-qa/references/testing_strategies.md diff --git a/.agent/skills/senior-qa/scripts/coverage_analyzer.py b/.claude/skills/senior-qa/scripts/coverage_analyzer.py similarity index 100% rename from .agent/skills/senior-qa/scripts/coverage_analyzer.py rename to .claude/skills/senior-qa/scripts/coverage_analyzer.py diff --git a/.agent/skills/senior-qa/scripts/e2e_test_scaffolder.py b/.claude/skills/senior-qa/scripts/e2e_test_scaffolder.py similarity index 100% rename from .agent/skills/senior-qa/scripts/e2e_test_scaffolder.py rename to .claude/skills/senior-qa/scripts/e2e_test_scaffolder.py diff --git a/.agent/skills/senior-qa/scripts/test_suite_generator.py b/.claude/skills/senior-qa/scripts/test_suite_generator.py similarity index 100% rename from .agent/skills/senior-qa/scripts/test_suite_generator.py rename to .claude/skills/senior-qa/scripts/test_suite_generator.py diff --git a/.github/workflows/deploy-ui.yml b/.github/workflows/deploy-ui.yml new file mode 100644 index 0000000..2c0f92f --- /dev/null +++ b/.github/workflows/deploy-ui.yml @@ -0,0 +1,45 @@ +name: Deploy Frontend +run-name: ${{ gitea.actor }} is deploying frontend 🚀 + +on: + push: + branches: + - main + - master + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest + + steps: + - name: Check out repository code + uses: actions/checkout@v3 + + - name: Build and Push Docker Image + run: | + docker build \ + --build-arg NEXT_PUBLIC_API_URL='${{ secrets.NEXT_PUBLIC_API_URL }}' \ + --build-arg NEXT_PUBLIC_AUTH_REQUIRED='false' \ + -t skript-ui . + + - name: Stop and Remove Existing Container + run: | + docker stop ui-skript-container || true + docker rm ui-skript-container || true + + - name: Run New Container + run: | + docker run -d \ + --name ui-skript-container \ + --restart unless-stopped \ + --network gitea-server_gitea \ + -p 1506:3000 \ + -e NEXTAUTH_URL='${{ secrets.NEXTAUTH_URL }}' \ + -e NEXTAUTH_SECRET='${{ secrets.NEXTAUTH_SECRET }}' \ + -e INTERNAL_API_URL='http://backend-skript-container:3000' \ + skript-ui + + - name: Cleanup + run: docker image prune -f diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..775e963 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# Base image +FROM node:20-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +WORKDIR /app +COPY package.json package-lock.json* ./ +RUN npm ci + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Pass build args as environment variables +ARG NEXT_PUBLIC_API_URL +ARG NEXT_PUBLIC_AUTH_REQUIRED +ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} +ENV NEXT_PUBLIC_AUTH_REQUIRED=${NEXT_PUBLIC_AUTH_REQUIRED} + +RUN npm run build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 +ENV PORT=3000 +# set hostname to localhost +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/next.config.ts b/next.config.ts index 11a5810..f62c4e9 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,6 +2,7 @@ import type { NextConfig } from "next"; import createNextIntlPlugin from "next-intl/plugin"; const nextConfig: NextConfig = { + output: 'standalone', experimental: { optimizePackageImports: ["@chakra-ui/react"], }, @@ -10,7 +11,7 @@ const nextConfig: NextConfig = { return [ { source: "/api/backend/:path*", - destination: "http://localhost:3000/api/:path*", + destination: `${process.env.INTERNAL_API_URL || "http://localhost:3000"}/api/:path*`, }, ]; }, diff --git a/package-lock.json b/package-lock.json index 52c8f33..92442d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5983,7 +5983,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", diff --git a/src/lib/api/ai-writer/service.ts b/src/lib/api/ai-writer/service.ts deleted file mode 100644 index 5dd3650..0000000 --- a/src/lib/api/ai-writer/service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { apiRequest } from "@/lib/api/api-service"; -import { ApiResponse } from "@/types/api-response"; -import { GenerateScriptDto, GeneratedScriptResponse } from "./types"; - -const generateScript = (projectId: string, data: GenerateScriptDto) => { - return apiRequest>({ - url: `/projects/${projectId}/writer/generate`, - client: "core", - method: "post", - data, - }); -}; - -export const aiWriterService = { - generateScript, -}; diff --git a/src/lib/api/ai-writer/types.ts b/src/lib/api/ai-writer/types.ts deleted file mode 100644 index 2fec379..0000000 --- a/src/lib/api/ai-writer/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface GenerateScriptDto { - topic: string; - contentType: string; - targetAudience: string[]; - speechStyle: string[]; - targetDuration: string; - tone: string; - language: string; - includeInterviews?: boolean; -} - -export interface GeneratedScriptResponse { - script: any[]; // ScriptSegment[] - seo: any; -} diff --git a/src/lib/api/ai-writer/use-hooks.ts b/src/lib/api/ai-writer/use-hooks.ts deleted file mode 100644 index 3d6dc78..0000000 --- a/src/lib/api/ai-writer/use-hooks.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useMutation } from "@tanstack/react-query"; -import { aiWriterService } from "./service"; -import { GenerateScriptDto } from "./types"; - -export function useGenerateScript() { - return useMutation({ - mutationFn: ({ projectId, data }: { projectId: string; data: GenerateScriptDto }) => - aiWriterService.generateScript(projectId, data), - }); -} diff --git a/src/lib/api/example/index.ts b/src/lib/api/example/index.ts index 0af7eac..3f88f7e 100644 --- a/src/lib/api/example/index.ts +++ b/src/lib/api/example/index.ts @@ -3,7 +3,7 @@ * Import all services and hooks from this single file * * Usage: - * import { authService, useLogin, adminRolesService, useGetAllRoles } from '@/lib/api/Example'; + * import { authService, useLogin, adminRolesService, useGetAllRoles } from '@/lib/api/example'; */ // Services diff --git a/src/lib/api/projects/service.ts b/src/lib/api/projects/service.ts deleted file mode 100644 index da0a49e..0000000 --- a/src/lib/api/projects/service.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { apiRequest } from "@/lib/api/api-service"; -import { ApiResponse } from "@/types/api-response"; -import { CreateProjectDto, Project, UpdateProjectDto } from "./types"; - -const getMyProjects = () => { - return apiRequest>({ - url: "/projects/my-projects", - client: "core", // or whatever specific client config - method: "get", - }); -}; - -const createProject = (data: CreateProjectDto) => { - return apiRequest>({ - url: "/projects", - client: "core", - method: "post", - data, - }); -}; -const getProject = (id: string) => { - return apiRequest>({ - url: `/projects/${id}`, - client: "core", - method: "get", - }); -}; - -const updateProject = (id: string, data: UpdateProjectDto) => { - return apiRequest>({ - url: `/projects/${id}`, - client: "core", - method: "put", - data, - }); -}; - -const deleteProject = (id: string) => { - return apiRequest>({ - url: `/projects/${id}`, - client: "core", - method: "delete", - }); -}; - -export const projectsService = { - getMyProjects, - createProject, - getProject, - updateProject, - deleteProject, -}; diff --git a/src/lib/api/projects/types.ts b/src/lib/api/projects/types.ts deleted file mode 100644 index e7ca47d..0000000 --- a/src/lib/api/projects/types.ts +++ /dev/null @@ -1,24 +0,0 @@ -export interface Project { - id: string; - userId: string; - topic: string; - contentType: string; - language: string; - targetDuration: string; - createdAt: string; - updatedAt: string; - // ... other fields matching backend Project model -} - -export interface CreateProjectDto { - topic: string; - contentType: string; - targetAudience: string[]; - speechStyle: string[]; - targetDuration: string; - tone: string; - language: string; - includeInterviews?: boolean; -} - -export interface UpdateProjectDto extends Partial { } diff --git a/src/lib/api/projects/use-hooks.ts b/src/lib/api/projects/use-hooks.ts deleted file mode 100644 index d7ebff4..0000000 --- a/src/lib/api/projects/use-hooks.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { projectsService } from "./service"; -import { CreateProjectDto, UpdateProjectDto } from "./types"; - -export const ProjectsQueryKeys = { - all: ["projects"] as const, - myProjects: () => [...ProjectsQueryKeys.all, "my-projects"] as const, - detail: (id: string) => [...ProjectsQueryKeys.all, "detail", id] as const, -}; - -export function useMyProjects() { - return useQuery({ - queryKey: ProjectsQueryKeys.myProjects(), - queryFn: () => projectsService.getMyProjects(), - }); -} - -export function useProject(id: string) { - return useQuery({ - queryKey: ProjectsQueryKeys.detail(id), - queryFn: () => projectsService.getProject(id), - enabled: !!id, - }); -} - -export function useCreateProject() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: (data: CreateProjectDto) => projectsService.createProject(data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ProjectsQueryKeys.myProjects() }); - }, - }); -} - -export function useUpdateProject() { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: ({ id, data }: { id: string; data: UpdateProjectDto }) => - projectsService.updateProject(id, data), - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ queryKey: ProjectsQueryKeys.detail(variables.id) }); - queryClient.invalidateQueries({ queryKey: ProjectsQueryKeys.myProjects() }); - }, - }); -}