* feat(backend): add LLM-powered feed enhancement
Add enhancement harness that fills feed item slots and
generates synthetic items via OpenRouter.
- LLM client with 30s timeout, reusable SDK instance
- Prompt builder with mini calendar and week overview
- arktype schema validation + JSON Schema for structured output
- Pure merge function with clock injection
- Defensive fallback in feed endpoint on enhancement failure
- Skips LLM call when no unfilled slots or no API key
Co-authored-by: Ona <no-reply@ona.com>
* refactor: move feed enhancement into UserSession
Move enhancement logic from HTTP handler into UserSession so the
transport layer has no knowledge of enhancement. UserSession.feed()
handles refresh, enhancement, and caching in one place.
- UserSession subscribes to engine updates and re-enhances eagerly
- Enhancement cache tracks source identity to prevent stale results
- UserSessionManager accepts config object with optional enhancer
- HTTP handler simplified to just call session.feed()
Co-authored-by: Ona <no-reply@ona.com>
* test: add schema sync tests for arktype/JSON Schema drift
Validates reference payloads against both the arktype schema
(parseEnhancementResult) and the OpenRouter JSON Schema structure.
Catches field additions/removals or type changes in either schema.
Co-authored-by: Ona <no-reply@ona.com>
* refactor: rename arktype schemas to match types
Co-authored-by: Ona <no-reply@ona.com>
---------
Co-authored-by: Ona <no-reply@ona.com>
Expose the user's current feed via GET /api/feed. Returns
cached feed from engine.lastFeed(), falling back to
engine.refresh() when no cache exists.
Auth middleware is injected as a dependency to allow test
substitution via mockAuthSessionMiddleware.
Co-authored-by: Ona <no-reply@ona.com>
Replace tRPC location.update mutation with POST /api/location
using Hono route + requireSession middleware. Extract auth
types (AuthUser, AuthToken) into auth/session.ts. Inject
sessionManager via Hono context local to location handlers.
Co-authored-by: Ona <no-reply@ona.com>
Replace per-source services (LocationService, WeatherService,
TflService, FeedEngineService) with a single UserSessionManager
that owns all per-user state. Source creation is delegated to
thin FeedSourceProvider implementations per source type.
Co-authored-by: Ona <no-reply@ona.com>
Manage per-user WeatherSource instances via FeedSourceProvider,
following the same pattern as LocationService. Wire into
FeedEngineService so weather data is included in the feed.
Co-authored-by: Ona <no-reply@ona.com>
- Add @trpc/server, @hono/trpc-server, zod dependencies
- Create tRPC context with BetterAuth session
- Create router with publicProcedure and protectedProcedure
- Mount tRPC at /trpc/* via Hono adapter
Co-authored-by: Ona <no-reply@ona.com>