yufan.me uses oRPC for all typed browser-to-server communication. Every HTTP call goes throughDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/syhily/yufan.me/llms.txt
Use this file to discover all available pages before exploring further.
/rpc/* — there are no ad-hoc fetch calls for data mutations. The browser client is built directly from typeof apiRouter, which means TypeScript enforces input and output types end-to-end without a separate code-generation step.
Base procedures and permission tiers
All procedures are built from one of four base procedure builders declared insrc/server/http/orpc-base.ts. Each base chains its own auth and role middleware; the leaf procedure picks one and inherits the guard automatically.
| Base | Guard | Used for |
|---|---|---|
publicProc | No auth gate; csrfGuard on non-GET | Anonymous + CSRF mutations |
authedProc | requireAuth + csrfGuard | Any logged-in user |
authorProc | requireRole('author') + csrfGuard | Authors and admins |
adminProc | requireRole('admin') + csrfGuard | Admins only |
os.$context<HandlerContext>(), so the Hono-to-context plumbing in app.ts is type-safe end-to-end. After an auth middleware resolves, context.viewer is narrowed from ViewerContext | null to the non-null ViewerContext type.
Procedure shape
Each controller exports a domain router built from procedures in this shape:server/domains/<x>/service.ts. Procedures throw ORPCError('CODE', { message }) which the onErrorHandler in server/http/errors.ts maps to HTTP status codes.
apiRouter shape
src/server/http/api-router.ts composes all domain controllers into a single apiRouter object. The admin sub-tree mirrors the /admin URL hierarchy. The browser client is typed as typeof apiRouter — adding a procedure to a controller and wiring it here is the only step needed to expose it to the client.
Resource routes
Non-JSON output is handled by native Hono routes inserver/http/resources/ — these do not go through oRPC:
| Route | Output |
|---|---|
/feed.xml | RSS 2.0 feed |
/atom.xml | Atom 1.0 feed |
/sitemap.xml | XML sitemap |
/og/* | Open Graph images (PNG) |
/calendar/:year/:month | Calendar SVG |
/rpc/* | oRPC JSON mount point |
server/http/middlewares/hono-rbac.ts::requireRoleMw.
OpenAPI spec
In development, the full OpenAPI specification is auto-generated fromapiRouter and available at:
/openapi.json— machine-readable spec/docs— interactive Swagger UI
CSRF protection
All non-GET procedures have acsrfGuard applied at the mount level — handlers never call validateRequestCsrf themselves. The browser oRPC client handles CSRF token injection automatically, so application code does not need to manage tokens directly.
Error handling
Procedures and services throwORPCError('CODE', { message }). The onErrorHandler in server/http/errors.ts maps oRPC error codes to HTTP status codes. Service layers must not throw HTTPException — only ORPCError or the domain’s own DomainError / ActionFailure types from server/infra/http/errors.