- createJwtUtils() factory with configurable issuer and expiry (jose)
- extractAuth() middleware for Fastify request auth extraction
- requireRole() guard with multi-role support
- hashPassword() / verifyPassword() via bcryptjs
- getCurrentUser() helper for Next.js API routes (generic TUser)
- AuthPayload, TokenPayload, JwtUtils types
- NO dependency on @bytelyst/config (reads JWT_SECRET from process.env directly)
- Peer deps: jose >=5.0.0, bcryptjs >=2.4.0
- Zod-based baseEnvSchema (PORT, HOST, NODE_ENV, CORS_ORIGIN, SERVICE_NAME, COSMOS_*)
- loadConfig() with extension support for service-specific fields
- loadProductIdentity() reads product.json or falls back to env vars
- getProductId() convenience function
- Replaces 5 duplicated product-config.ts files across LysnrAI
- Peer dep: zod >=3.20.0
- Singleton CosmosClient with env var config (COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE)
- Simple getContainer() for services
- Container registry with registerContainers(), getRegisteredContainer(), initializeAllContainers() for dashboards
- ContainerConfig type with partitionKeyPath and optional defaultTtl
- _resetClient() and _resetRegistry() for test isolation
- Peer dep: @azure/cosmos >=4.0.0
- ServiceError base class with statusCode, message, details
- HTTP errors: BadRequest, Unauthorized, Forbidden, NotFound, Conflict, TooManyRequests
- 10 tests passing (vitest)
- Superset of all 4 service error files in LysnrAI