feat: scaffold Hono server with auth and health check
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
3
server/.env.example
Normal file
3
server/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
DATABASE_URL="postgres://user:password@host:port/db-name"
|
||||
PORT=8080
|
||||
CORS_ORIGIN="http://localhost:5173"
|
||||
12
server/Dockerfile
Normal file
12
server/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM oven/bun:1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY packages/shared ./packages/shared
|
||||
COPY server ./server
|
||||
|
||||
WORKDIR /app/server
|
||||
RUN bun install
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["bun", "src/index.ts"]
|
||||
21
server/package.json
Normal file
21
server/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@droidclaw/server",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun --watch src/index.ts",
|
||||
"start": "bun src/index.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@droidclaw/shared": "workspace:*",
|
||||
"hono": "^4.7.0",
|
||||
"better-auth": "^1.3.27",
|
||||
"drizzle-orm": "^0.44.5",
|
||||
"postgres": "^3.4.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.0",
|
||||
"typescript": "^5.9.2"
|
||||
}
|
||||
}
|
||||
11
server/src/auth.ts
Normal file
11
server/src/auth.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { betterAuth } from "better-auth";
|
||||
import { apiKey } from "better-auth/plugins";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import { db } from "./db.js";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
provider: "pg",
|
||||
}),
|
||||
plugins: [apiKey()],
|
||||
});
|
||||
6
server/src/db.ts
Normal file
6
server/src/db.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import { env } from "./env.js";
|
||||
|
||||
const client = postgres(env.DATABASE_URL);
|
||||
export const db = drizzle(client);
|
||||
9
server/src/env.ts
Normal file
9
server/src/env.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export const env = {
|
||||
DATABASE_URL: process.env.DATABASE_URL!,
|
||||
PORT: parseInt(process.env.PORT || "8080"),
|
||||
CORS_ORIGIN: process.env.CORS_ORIGIN || "http://localhost:5173",
|
||||
};
|
||||
|
||||
if (!env.DATABASE_URL) {
|
||||
throw new Error("DATABASE_URL is not set");
|
||||
}
|
||||
44
server/src/index.ts
Normal file
44
server/src/index.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Hono } from "hono";
|
||||
import { cors } from "hono/cors";
|
||||
import { auth } from "./auth.js";
|
||||
import { env } from "./env.js";
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
// CORS for dashboard
|
||||
app.use(
|
||||
"*",
|
||||
cors({
|
||||
origin: env.CORS_ORIGIN,
|
||||
allowHeaders: ["Content-Type", "Authorization"],
|
||||
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
||||
credentials: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Better Auth handler
|
||||
app.on(["POST", "GET"], "/api/auth/*", (c) => {
|
||||
return auth.handler(c.req.raw);
|
||||
});
|
||||
|
||||
// Health check
|
||||
app.get("/health", (c) => c.json({ status: "ok" }));
|
||||
|
||||
// Start server with WebSocket support
|
||||
const server = Bun.serve({
|
||||
port: env.PORT,
|
||||
fetch: app.fetch,
|
||||
websocket: {
|
||||
open(ws) {
|
||||
console.log("WebSocket connected");
|
||||
},
|
||||
message(ws, message) {
|
||||
// placeholder — Task 4 implements device/dashboard handlers
|
||||
},
|
||||
close(ws) {
|
||||
console.log("WebSocket disconnected");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Server running on port ${server.port}`);
|
||||
17
server/tsconfig.json
Normal file
17
server/tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"types": ["bun"],
|
||||
"paths": {
|
||||
"@droidclaw/shared": ["../packages/shared/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user