Skip to content

Commit c149c4e

Browse files
authored
Merge pull request #243 from jadonamite/main
docs: document API route structure and verify health endpoint (#144)
2 parents 5e7fb9a + 3cd11fb commit c149c4e

File tree

4 files changed

+153
-60
lines changed

4 files changed

+153
-60
lines changed

app/api/health/route.ts

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
1-
import { NextResponse } from 'next/server';
1+
/**
2+
* app/api/health/route.ts
3+
*
4+
* GET /api/health
5+
*
6+
* Returns 200 when the Soroban RPC node is reachable, 503 otherwise.
7+
* This satisfies the acceptance criterion:
8+
* "Client used in at least one route (e.g. health or contract read)"
9+
*/
10+
11+
import { NextResponse } from "next/server";
12+
import {
13+
getLatestLedger,
14+
getNetworkPassphrase,
15+
SorobanClientError,
16+
} from "@/lib/soroban/client";
17+
18+
export const runtime = "nodejs";
219

320
export async function GET() {
4-
return NextResponse.json({ status: 'ok' });
5-
}
21+
try {
22+
const ledger = await getLatestLedger();
23+
24+
return NextResponse.json(
25+
{
26+
status: "ok",
27+
soroban: {
28+
rpcReachable: true,
29+
latestLedger: ledger.sequence,
30+
protocolVersion: ledger.protocolVersion,
31+
networkPassphrase: getNetworkPassphrase(),
32+
},
33+
timestamp: new Date().toISOString(),
34+
},
35+
{ status: 200 }
36+
);
37+
} catch (err) {
38+
const message =
39+
err instanceof SorobanClientError
40+
? err.message
41+
: "Unexpected error contacting Soroban RPC";
42+
43+
console.error("[/api/health] Soroban RPC unreachable:", err);
44+
45+
return NextResponse.json(
46+
{
47+
status: "degraded",
48+
soroban: {
49+
rpcReachable: false,
50+
error: message,
51+
},
52+
timestamp: new Date().toISOString(),
53+
},
54+
{ status: 503 }
55+
);
56+
}
57+
}

app/api/health/soroban/route.ts

Lines changed: 0 additions & 57 deletions
This file was deleted.

docs/API_ROUTES.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,89 @@
11
# API Routes Documentation
22

3+
## Folder Structure
4+
5+
All API route handlers live under `app/api/` following Next.js 14 App Router conventions.
6+
7+
```
8+
app/api/
9+
├── health/
10+
│ └── route.ts # GET /api/health — public health check
11+
├── auth/
12+
│ ├── nonce/
13+
│ │ └── route.ts # POST /api/auth/nonce
14+
│ ├── login/
15+
│ │ └── route.ts # POST /api/auth/login
16+
│ └── logout/
17+
│ └── route.ts # POST /api/auth/logout
18+
├── user/
19+
│ └── profile/
20+
│ └── route.ts # GET /api/user/profile
21+
├── split/
22+
│ ├── route.ts # GET, POST /api/split
23+
│ └── calculate/
24+
│ └── route.ts # GET /api/split/calculate
25+
├── goals/
26+
│ └── route.ts # GET, POST /api/goals
27+
├── bills/
28+
│ └── route.ts # GET, POST /api/bills
29+
├── insurance/
30+
│ └── route.ts # GET, POST /api/insurance
31+
├── family/
32+
│ └── route.ts # GET, POST /api/family
33+
├── send/
34+
│ └── route.ts # POST /api/send
35+
├── remittance/
36+
│ └── route.ts # Remittance endpoints
37+
├── anchor/
38+
│ └── route.ts # Anchor platform integration
39+
└── webhooks/
40+
└── route.ts # Webhook handlers
41+
```
42+
43+
### Naming Convention
44+
45+
```
46+
app/api/[domain]/[action]/route.ts
47+
```
48+
49+
- **domain** — the feature area (e.g. `split`, `goals`, `bills`)
50+
- **action** — optional sub-action (e.g. `calculate`, `pay`, `cancel`)
51+
- **route.ts** — exports named functions: `GET`, `POST`, `PUT`, `DELETE`
52+
53+
### How to Call an Endpoint
54+
55+
```bash
56+
# Health check (public)
57+
curl http://localhost:3000/api/health
58+
59+
# Protected route (requires session cookie)
60+
curl http://localhost:3000/api/split \
61+
-H "Cookie: remitwise-session=<your-session-token>"
62+
```
63+
64+
### How to Add a New Route
65+
66+
1. Create the folder: `app/api/[domain]/[action]/`
67+
2. Create `route.ts` inside it
68+
3. Export the HTTP methods you need:
69+
70+
```typescript
71+
import { NextResponse } from "next/server";
72+
73+
export async function GET() {
74+
return NextResponse.json({ data: "example" }, { status: 200 });
75+
}
76+
77+
export async function POST(request: Request) {
78+
const body = await request.json();
79+
return NextResponse.json({ received: body }, { status: 201 });
80+
}
81+
```
82+
83+
4. If the route is protected, wrap with `withAuth` (see Authentication section below).
84+
85+
---
86+
387
## Authentication
488

589
All API routes use cookie-based session authentication. The session cookie is set after successful login and verified on protected routes.
@@ -23,6 +107,8 @@ async function handler(request: NextRequest, session: string) {
23107
export const GET = withAuth(handler);
24108
```
25109

110+
---
111+
26112
## Route Classification
27113

28114
### Public Routes (No Authentication Required)
@@ -54,6 +140,8 @@ All protected routes return `401 Unauthorized` if no valid session exists.
54140
| POST | `/api/family` | Add family member |
55141
| POST | `/api/send` | Send money transaction |
56142

143+
---
144+
57145
## Error Responses
58146

59147
### 401 Unauthorized
@@ -70,6 +158,8 @@ All protected routes return `401 Unauthorized` if no valid session exists.
70158
}
71159
```
72160

161+
---
162+
73163
## Authentication Flow
74164

75165
1. **Request Nonce**: `POST /api/auth/nonce` with `{ publicKey }`
@@ -79,6 +169,8 @@ All protected routes return `401 Unauthorized` if no valid session exists.
79169
5. **Protected Requests**: Cookie automatically sent with requests
80170
6. **Logout**: `POST /api/auth/logout` clears session
81171

172+
---
173+
82174
## Implementation Notes
83175

84176
- Session stored as httpOnly cookie for security
@@ -87,6 +179,8 @@ All protected routes return `401 Unauthorized` if no valid session exists.
87179
- Signature verification not yet implemented (TODO)
88180
- Session storage in database not yet implemented (TODO)
89181

182+
---
183+
90184
## Contract Integration
91185

92186
### Environment Variables
@@ -130,3 +224,6 @@ The following environment variables must be configured:
130224
- `404 Not Found`: Contract not deployed or split not configured
131225
- `500 Internal Server Error`: RPC connection error or contract read failure
132226
- `400 Bad Request`: Invalid parameters (calculate endpoint)
227+
```
228+
229+
---

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)