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 '@styles/index.css';
|
||||
import Home from '@pages/home';
|
||||
import Login from '@pages/login';
|
||||
import Application from '@pages/application';
|
||||
|
||||
import '@styles/index.css';
|
||||
const App = () => {
|
||||
return (
|
||||
<Routes>
|
||||
@@ -1,4 +1,7 @@
|
||||
import { useState } from "react";
|
||||
|
||||
function Application() {
|
||||
const [apps, setApps] = useState<Application[]>([]);
|
||||
return (
|
||||
<div>
|
||||
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",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "",
|
||||
"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"
|
||||
"dev": "pnpm run dev:server && pnpm run dev:web"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arco-plugins/unplugin-react": "2.0.0-beta.5",
|
||||
"@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"
|
||||
"@biomejs/biome": "2.0.6"
|
||||
},
|
||||
"keywords": ["ci", "ark", "ark-ci"],
|
||||
"author": "hurole",
|
||||
"license": "ISC",
|
||||
"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