Skip to content

Commit 0899645

Browse files
authored
Merge pull request #5 from unicef/app-layer-scaffolding
Add app layer scaffolding: Hono API + React SPA
2 parents 1dbfbe8 + a467e8a commit 0899645

32 files changed

Lines changed: 2213 additions & 9 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,6 @@ coverage/
4444

4545
# pnpm
4646
.pnpm-store/
47+
48+
# Local working docs (not tracked)
49+
.local-docs/

apps/api/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@adt/api",
3+
"version": "0.1.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"dev": "tsx watch src/index.ts"
8+
},
9+
"dependencies": {
10+
"@adt/llm": "workspace:*",
11+
"@adt/pdf": "workspace:*",
12+
"@adt/pipeline": "workspace:*",
13+
"@adt/storage": "workspace:*",
14+
"@adt/types": "workspace:*",
15+
"@hono/node-server": "^1.14.0",
16+
"hono": "^4.7.0",
17+
"js-yaml": "^4.1.0"
18+
}
19+
}

apps/api/src/.gitkeep

Whitespace-only changes.

apps/api/src/app.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Hono } from "hono"
2+
import { cors } from "hono/cors"
3+
import { logger } from "hono/logger"
4+
import { errorHandler } from "./middleware/error-handler.js"
5+
import { healthRoutes } from "./routes/health.js"
6+
import { bookRoutes } from "./routes/books.js"
7+
8+
const app = new Hono()
9+
10+
app.use("*", logger())
11+
app.use(
12+
"*",
13+
cors({
14+
origin: "http://localhost:5173",
15+
})
16+
)
17+
app.onError(errorHandler)
18+
19+
app.route("/api", healthRoutes)
20+
app.route("/api", bookRoutes)
21+
22+
export default app

apps/api/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { serve } from "@hono/node-server"
2+
import app from "./app.js"
3+
4+
const port = parseInt(process.env.PORT ?? "3001", 10)
5+
6+
serve({ fetch: app.fetch, port }, (info) => {
7+
console.log(`API server running on http://localhost:${info.port}`)
8+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { ErrorHandler } from "hono"
2+
import { HTTPException } from "hono/http-exception"
3+
4+
export const errorHandler: ErrorHandler = (err, c) => {
5+
if (err instanceof HTTPException) {
6+
return c.json({ error: err.message }, err.status)
7+
}
8+
console.error(err)
9+
return c.json({ error: "Internal server error" }, 500)
10+
}

apps/api/src/routes/books.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Hono } from "hono"
2+
3+
export const bookRoutes = new Hono()
4+
5+
// Book CRUD routes will be implemented in Increment 2

apps/api/src/routes/health.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { describe, it, expect } from "vitest"
2+
import app from "../app.js"
3+
4+
describe("GET /api/health", () => {
5+
it("returns 200 with status ok", async () => {
6+
const res = await app.request("/api/health")
7+
expect(res.status).toBe(200)
8+
const body = await res.json()
9+
expect(body).toEqual({ status: "ok" })
10+
})
11+
})

apps/api/src/routes/health.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Hono } from "hono"
2+
3+
export const healthRoutes = new Hono()
4+
5+
healthRoutes.get("/health", (c) => {
6+
return c.json({ status: "ok" })
7+
})
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Book management service will be implemented in Increment 2
2+
export {}

0 commit comments

Comments
 (0)