feat(api): Hono backend skeleton with /health endpoint and test
This commit is contained in:
30
apps/api/package.json
Normal file
30
apps/api/package.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "@solelog/api",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsx watch src/index.ts",
|
||||||
|
"start": "tsx src/index.ts",
|
||||||
|
"test": "vitest run",
|
||||||
|
"test:watch": "vitest",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"db:generate": "drizzle-kit generate",
|
||||||
|
"db:migrate": "tsx src/db/migrate.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@hono/node-server": "^1.13.7",
|
||||||
|
"@libsql/client": "^0.14.0",
|
||||||
|
"@solelog/shared": "workspace:*",
|
||||||
|
"better-auth": "^1.1.7",
|
||||||
|
"drizzle-orm": "^0.36.4",
|
||||||
|
"hono": "^4.6.14",
|
||||||
|
"zod": "^3.23.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"drizzle-kit": "^0.30.1",
|
||||||
|
"tsx": "^4.19.2",
|
||||||
|
"typescript": "^5.7.2",
|
||||||
|
"vitest": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
8
apps/api/src/app.ts
Normal file
8
apps/api/src/app.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { Hono } from 'hono';
|
||||||
|
import { health } from './routes/health';
|
||||||
|
|
||||||
|
export function createApp(): Hono {
|
||||||
|
const app = new Hono();
|
||||||
|
app.route('/', health);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
6
apps/api/src/env.ts
Normal file
6
apps/api/src/env.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const env = {
|
||||||
|
DATABASE_URL: process.env.DATABASE_URL ?? 'file:./data/app.db',
|
||||||
|
BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET ?? 'dev-insecure-secret-change-me',
|
||||||
|
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL ?? 'http://localhost:3000',
|
||||||
|
PORT: Number(process.env.PORT ?? 3000),
|
||||||
|
};
|
||||||
8
apps/api/src/index.ts
Normal file
8
apps/api/src/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { serve } from '@hono/node-server';
|
||||||
|
import { createApp } from './app';
|
||||||
|
import { env } from './env';
|
||||||
|
|
||||||
|
const app = createApp();
|
||||||
|
serve({ fetch: app.fetch, port: env.PORT }, (info) => {
|
||||||
|
console.log(`API listening on http://localhost:${info.port}`);
|
||||||
|
});
|
||||||
9
apps/api/src/routes/health.ts
Normal file
9
apps/api/src/routes/health.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Hono } from 'hono';
|
||||||
|
import { HealthResponse } from '@solelog/shared';
|
||||||
|
|
||||||
|
export const health = new Hono();
|
||||||
|
|
||||||
|
health.get('/health', (c) => {
|
||||||
|
const body: HealthResponse = { status: 'ok' };
|
||||||
|
return c.json(body);
|
||||||
|
});
|
||||||
11
apps/api/test/health.test.ts
Normal file
11
apps/api/test/health.test.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { createApp } from '../src/app';
|
||||||
|
|
||||||
|
describe('GET /health', () => {
|
||||||
|
it('returns { status: "ok" }', async () => {
|
||||||
|
const app = createApp();
|
||||||
|
const res = await app.request('/health');
|
||||||
|
expect(res.status).toBe(200);
|
||||||
|
expect(await res.json()).toEqual({ status: 'ok' });
|
||||||
|
});
|
||||||
|
});
|
||||||
2
apps/api/test/setup.ts
Normal file
2
apps/api/test/setup.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// Placeholder until Task 3 adds DB migration to the test setup.
|
||||||
|
export {};
|
||||||
15
apps/api/tsconfig.json
Normal file
15
apps/api/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"types": ["node"],
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": ["src", "test"]
|
||||||
|
}
|
||||||
9
apps/api/vitest.config.ts
Normal file
9
apps/api/vitest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
environment: 'node',
|
||||||
|
setupFiles: ['./test/setup.ts'],
|
||||||
|
fileParallelism: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user