Merged
Conversation
- 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>
app/ai-assistant/src/application/middleware/localAuthMiddleware.ts
Dismissed
Show dismissed
Hide dismissed
…es Secret Signed-off-by: Patricia Ramos <patri@kabila.app>
Signed-off-by: Patricia Ramos <patri@kabila.app>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This branch introduces a local development setup for the
ai-assistantservice, 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
localAuthMiddleware.ts): New FastifypreHandlerhook that verifies PASETO v4 tokens directly, extractinguserIdfrom the payload and injecting it asx-user-idheader — mirrors what SPOE does in production. Expired tokens are accepted in local mode (ignoreExp: true) to ease development.ENVIRONMENT=local,@fastify/corsis registered with configurableALLOWED_ORIGIN(defaults tohttp://localhost:5173), allowing the frontend to call the API directly without a proxy.environment.ts): Replaced scatteredprocess.env.*reads with a single typedenvironmentobject.isLocal()andisDevelopment()are now functions (not booleans) to always reflect the current value.errors.ts): Replaced the single genericAPIErrorclass with a full hierarchy:AuthenticationError,AuthorizationError,NotFoundError,ValidationError,RateLimitError,UsageLimitError,ConflictError,ExternalServiceError,InternalServerError. All errors carry a machine-readableErrorReasonenum value.index.ts: The global error handler now distinguishes betweenAPIErrorsubclasses, OpenAIAI_APICallError, Zod validation errors, and unknown errors — each returning a consistent{ reason, message, statusCode, details, timestamp }shape.constants.ts: ExtractedBASE_PATHandHEALTH_PATHinto a shared constants file to avoid duplication..env-tplupdated: AddedENVIRONMENT,PASETO_V4_PUBLIC_KEY_HEX, andALLOWED_ORIGINvariables with inline documentation.ChatService/UserAIKeyService/KmsService: Allthrow new APIError(...)calls replaced with the appropriate typed subclass andErrorReason.validateAIKeynow catches OpenAI SDK errors and surfaces them asValidationErrorwith proper reason codes instead of letting them bubble up unhandled.