Skip to content

Feat/ai assistant local dev setup#5

Merged
pat-rg merged 4 commits intodevelopfrom
feat/ai-assistant-local-dev-setup
Feb 27, 2026
Merged

Feat/ai assistant local dev setup#5
pat-rg merged 4 commits intodevelopfrom
feat/ai-assistant-local-dev-setup

Conversation

@pat-rg
Copy link
Collaborator

@pat-rg pat-rg commented Feb 27, 2026

Summary

This branch introduces a local development setup for the ai-assistant service, enabling developers to run the service locally without requiring HAProxy + SPOE in front. It also standardizes API error handling across the entire service with a typed error hierarchy.

Issues Resolved

https://github.com/hashgraph/hedera-portal/issues/505

Changes Made

  • Local auth middleware (localAuthMiddleware.ts): New Fastify preHandler hook that verifies PASETO v4 tokens directly, extracting userId from the payload and injecting it as x-user-id header — mirrors what SPOE does in production. Expired tokens are accepted in local mode (ignoreExp: true) to ease development.
  • CORS support for local mode: When ENVIRONMENT=local, @fastify/cors is registered with configurable ALLOWED_ORIGIN (defaults to http://localhost:5173), allowing the frontend to call the API directly without a proxy.
  • Environment config consolidation (environment.ts): Replaced scattered process.env.* reads with a single typed environment object. isLocal() and isDevelopment() are now functions (not booleans) to always reflect the current value.
  • Typed error hierarchy (errors.ts): Replaced the single generic APIError class with a full hierarchy: AuthenticationError, AuthorizationError, NotFoundError, ValidationError, RateLimitError, UsageLimitError, ConflictError, ExternalServiceError, InternalServerError. All errors carry a machine-readable ErrorReason enum value.
  • Standardized error responses in index.ts: The global error handler now distinguishes between APIError subclasses, OpenAI AI_APICallError, Zod validation errors, and unknown errors — each returning a consistent { reason, message, statusCode, details, timestamp } shape.
  • constants.ts: Extracted BASE_PATH and HEALTH_PATH into a shared constants file to avoid duplication.
  • .env-tpl updated: Added ENVIRONMENT, PASETO_V4_PUBLIC_KEY_HEX, and ALLOWED_ORIGIN variables with inline documentation.
  • ChatService / UserAIKeyService / KmsService: All throw new APIError(...) calls replaced with the appropriate typed subclass and ErrorReason.
  • OpenAI key validation: validateAIKey now catches OpenAI SDK errors and surfaces them as ValidationError with proper reason codes instead of letting them bubble up unhandled.
  • Move OPENAI_API_KEY and Redis password to Kubernetes Secret

- Add localAuthMiddleware that replicates SPOE/HAProxy auth flow for local env
- Register CORS and auth middleware globally only when ENVIRONMENT=local
- Use ENVIRONMENT var instead of NODE_ENV for isDevelopment/isLocal checks
- Load dotenv in environment.ts to ensure vars are available before logger init
- Enable pino-pretty logs only when ENVIRONMENT=local
- Use REDIS_URL for local Redis connection

Signed-off-by: Patricia Ramos <patri@kabila.app>
…middleware

- Replace scattered dotenv.config() calls with a single import 'dotenv/config' at entrypoint
- Introduce environment object in utils/environment.ts centralizing all env var reads (PORT, HOST, LOG_LEVEL, ALLOWED_ORIGIN, PASETO_V4_PUBLIC_KEY_HEX)
- Add utils/constants.ts with BASE_PATH and HEALTH_PATH constants
- Restrict CORS in local mode to a configurable origin (ALLOWED_ORIGIN) with explicit allowed headers and methods
- Enable pino-pretty transport in development environment (not only local)
- Log warning when running without CORS/auth middleware (non-local envs)
- Add PASETO token verification error logging in localAuthMiddleware
- Add ENVIRONMENT=development to ai-assistant Helm values
- Extend HAProxy CORS allowed headers with x-stainless-* headers sent by the OpenAI SDK
- Rewrite README with current architecture, env vars table, and HTTP API docs
- Update .env-tpl with new variables and inline comments

Signed-off-by: Patricia Ramos <patri@kabila.app>
…es Secret

Signed-off-by: Patricia Ramos <patri@kabila.app>
Signed-off-by: Patricia Ramos <patri@kabila.app>
@pat-rg pat-rg merged commit 00743ee into develop Feb 27, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant