feat: add backend
This commit is contained in:
5
apps/server/.gitignore
vendored
Normal file
5
apps/server/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
node_modules
|
||||||
|
# Keep environment variables out of version control
|
||||||
|
.env
|
||||||
|
|
||||||
|
/generated/prisma
|
||||||
10
apps/server/app.ts
Normal file
10
apps/server/app.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import Koa from 'koa';
|
||||||
|
import { registerMiddlewares } from './middlewares/index.ts';
|
||||||
|
|
||||||
|
const app = new Koa();
|
||||||
|
|
||||||
|
registerMiddlewares(app);
|
||||||
|
|
||||||
|
app.listen(3000, () => {
|
||||||
|
console.log('server started at http://localhost:3000');
|
||||||
|
});
|
||||||
11
apps/server/controllers/application.ts
Normal file
11
apps/server/controllers/application.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import type { Context } from 'koa';
|
||||||
|
import prisma from '../libs/db.ts';
|
||||||
|
|
||||||
|
export async function list(ctx: Context) {
|
||||||
|
const list = await prisma.application.findMany({
|
||||||
|
where: {
|
||||||
|
valid: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ctx.body = list;
|
||||||
|
}
|
||||||
7
apps/server/libs/db.ts
Normal file
7
apps/server/libs/db.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { PrismaClient } from '../generated/prisma/index.js'
|
||||||
|
|
||||||
|
const prismaClientSingleton = () => {
|
||||||
|
return new PrismaClient();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default prismaClientSingleton();
|
||||||
10
apps/server/middlewares/index.ts
Normal file
10
apps/server/middlewares/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Router } from './router.ts';
|
||||||
|
import { ResponseTime } from './responseTime.ts';
|
||||||
|
import type Koa from 'koa';
|
||||||
|
|
||||||
|
export function registerMiddlewares(app: Koa) {
|
||||||
|
const router = new Router();
|
||||||
|
const responseTime = new ResponseTime();
|
||||||
|
responseTime.apply(app);
|
||||||
|
router.apply(app);
|
||||||
|
}
|
||||||
13
apps/server/middlewares/responseTime.ts
Normal file
13
apps/server/middlewares/responseTime.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import type { Middleware } from './types.ts';
|
||||||
|
import type Koa from 'koa';
|
||||||
|
|
||||||
|
export class ResponseTime implements Middleware {
|
||||||
|
apply(app: Koa): void {
|
||||||
|
app.use(async (ctx, next) => {
|
||||||
|
const start = Date.now();
|
||||||
|
await next();
|
||||||
|
const ms = Date.now() - start;
|
||||||
|
ctx.set('X-Response-Time', `${ms}ms`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
19
apps/server/middlewares/router.ts
Normal file
19
apps/server/middlewares/router.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import KoaRouter from '@koa/router';
|
||||||
|
import type Koa from 'koa';
|
||||||
|
import type { Middleware } from './types.ts';
|
||||||
|
import * as application from '../controllers/application.ts';
|
||||||
|
|
||||||
|
export class Router implements Middleware {
|
||||||
|
private router: KoaRouter;
|
||||||
|
constructor() {
|
||||||
|
this.router = new KoaRouter({
|
||||||
|
prefix: '/api',
|
||||||
|
});
|
||||||
|
this.router.get('/application/list', application.list);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(app: Koa) {
|
||||||
|
app.use(this.router.routes());
|
||||||
|
app.use(this.router.allowedMethods());
|
||||||
|
}
|
||||||
|
}
|
||||||
5
apps/server/middlewares/types.ts
Normal file
5
apps/server/middlewares/types.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import type Koa from 'koa';
|
||||||
|
|
||||||
|
export abstract class Middleware {
|
||||||
|
abstract apply(app: Koa, options?: unknown): void;
|
||||||
|
}
|
||||||
27
apps/server/package.json
Normal file
27
apps/server/package.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "server",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsx watch ./app.ts"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"type": "module",
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@koa/router": "^14.0.0",
|
||||||
|
"@prisma/client": "^6.15.0",
|
||||||
|
"koa": "^3.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tsconfig/node-ts": "^23.6.1",
|
||||||
|
"@tsconfig/node22": "^22.0.2",
|
||||||
|
"@types/koa": "^3.0.0",
|
||||||
|
"@types/koa__router": "^12.0.4",
|
||||||
|
"@types/node": "^24.3.0",
|
||||||
|
"prisma": "^6.15.0",
|
||||||
|
"tsx": "^4.20.5",
|
||||||
|
"typescript": "^5.9.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
apps/server/prisma/data/dev.db
Normal file
BIN
apps/server/prisma/data/dev.db
Normal file
Binary file not shown.
35
apps/server/prisma/schema.prisma
Normal file
35
apps/server/prisma/schema.prisma
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// This is your Prisma schema file,
|
||||||
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||||
|
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
output = "../generated/prisma"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "sqlite"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Application {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
description String?
|
||||||
|
repository String
|
||||||
|
valid Int @default(1)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
createdBy String
|
||||||
|
updatedBy String
|
||||||
|
}
|
||||||
|
|
||||||
|
model Environment {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
description String?
|
||||||
|
valid Int @default(1)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
createdBy String
|
||||||
|
updatedBy String
|
||||||
|
}
|
||||||
6
apps/server/tsconfig.json
Normal file
6
apps/server/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"@tsconfig/node22/tsconfig.json",
|
||||||
|
"@tsconfig/node-ts/tsconfig.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
32
apps/web/package.json
Normal file
32
apps/web/package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "web",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "rsbuild build",
|
||||||
|
"check": "biome check --write",
|
||||||
|
"dev": "rsbuild dev --open",
|
||||||
|
"format": "biome format --write",
|
||||||
|
"preview": "rsbuild preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@arco-design/web-react": "^2.66.4",
|
||||||
|
"react": "^19.1.1",
|
||||||
|
"react-dom": "^19.1.1",
|
||||||
|
"react-router": "^7.8.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@arco-plugins/unplugin-react": "2.0.0-beta.5",
|
||||||
|
"@rsbuild/core": "^1.4.13",
|
||||||
|
"@rsbuild/plugin-less": "^1.4.0",
|
||||||
|
"@rsbuild/plugin-react": "^1.3.4",
|
||||||
|
"@rsbuild/plugin-svgr": "^1.2.2",
|
||||||
|
"@tailwindcss/postcss": "^4.1.11",
|
||||||
|
"@types/react": "^19.1.9",
|
||||||
|
"@types/react-dom": "^19.1.7",
|
||||||
|
"tailwindcss": "^4.1.11",
|
||||||
|
"typescript": "^5.9.2"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@9.15.2+sha512.93e57b0126f0df74ce6bff29680394c0ba54ec47246b9cf321f0121d8d9bb03f750a705f24edc3c1180853afd7c2c3b94196d0a3d53d3e069d9e2793ef11f321"
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
0
src/env.d.ts → apps/web/src/env.d.ts
vendored
0
src/env.d.ts → apps/web/src/env.d.ts
vendored
@@ -1,9 +1,9 @@
|
|||||||
import { Route, Routes } from 'react-router';
|
import { Route, Routes } from 'react-router';
|
||||||
import '@styles/index.css';
|
|
||||||
import Home from '@pages/home';
|
import Home from '@pages/home';
|
||||||
import Login from '@pages/login';
|
import Login from '@pages/login';
|
||||||
import Application from '@pages/application';
|
import Application from '@pages/application';
|
||||||
|
|
||||||
|
import '@styles/index.css';
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
function Application() {
|
function Application() {
|
||||||
|
const [apps, setApps] = useState<Application[]>([]);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
application
|
application
|
||||||
15
apps/web/src/pages/application/types.ts
Normal file
15
apps/web/src/pages/application/types.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
enum AppStatus {
|
||||||
|
Idle = "Pending",
|
||||||
|
Running = "Running",
|
||||||
|
Stopped = "Stopped",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Application {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
git: string;
|
||||||
|
env: Record<string, string>;
|
||||||
|
createdAt: string;
|
||||||
|
status: AppStatus;
|
||||||
|
}
|
||||||
32
package.json
32
package.json
@@ -1,33 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "foka-ci",
|
"name": "ark-ci",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"description": "",
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rsbuild build",
|
"dev": "pnpm run dev:server && pnpm run dev:web"
|
||||||
"check": "biome check --write",
|
|
||||||
"dev": "rsbuild dev --open",
|
|
||||||
"format": "biome format --write",
|
|
||||||
"preview": "rsbuild preview"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@arco-design/web-react": "^2.66.4",
|
|
||||||
"react": "^19.1.1",
|
|
||||||
"react-dom": "^19.1.1",
|
|
||||||
"react-router": "^7.8.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arco-plugins/unplugin-react": "2.0.0-beta.5",
|
"@biomejs/biome": "2.0.6"
|
||||||
"@biomejs/biome": "2.0.6",
|
|
||||||
"@rsbuild/core": "^1.4.13",
|
|
||||||
"@rsbuild/plugin-less": "^1.4.0",
|
|
||||||
"@rsbuild/plugin-react": "^1.3.4",
|
|
||||||
"@rsbuild/plugin-svgr": "^1.2.2",
|
|
||||||
"@tailwindcss/postcss": "^4.1.11",
|
|
||||||
"@types/react": "^19.1.9",
|
|
||||||
"@types/react-dom": "^19.1.7",
|
|
||||||
"tailwindcss": "^4.1.11",
|
|
||||||
"typescript": "^5.9.2"
|
|
||||||
},
|
},
|
||||||
|
"keywords": ["ci", "ark", "ark-ci"],
|
||||||
|
"author": "hurole",
|
||||||
|
"license": "ISC",
|
||||||
"packageManager": "pnpm@9.15.2+sha512.93e57b0126f0df74ce6bff29680394c0ba54ec47246b9cf321f0121d8d9bb03f750a705f24edc3c1180853afd7c2c3b94196d0a3d53d3e069d9e2793ef11f321"
|
"packageManager": "pnpm@9.15.2+sha512.93e57b0126f0df74ce6bff29680394c0ba54ec47246b9cf321f0121d8d9bb03f750a705f24edc3c1180853afd7c2c3b94196d0a3d53d3e069d9e2793ef11f321"
|
||||||
}
|
}
|
||||||
|
|||||||
1508
pnpm-lock.yaml
generated
1508
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
2
pnpm-workspace.yaml
Normal file
2
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
- 'apps/*'
|
||||||
Reference in New Issue
Block a user