Skip to main content

hbf-core Gotchas

Package-specific pitfalls and non-obvious patterns. Loaded automatically by workflow commands.

Jackson Serialization

  • Never use @JsonProperty(WRITE_ONLY) on fields crossing the hbf-core to hbf-bot boundary: BotDeployment API serializes via Jackson. WRITE_ONLY strips fields from the response, so hbf-bot receives null. Use @PrivateProperty instead (only affects the AutoMapped public org info path).
  • OIDCIntegration.clientSecret has NO annotation: The base class handles secret visibility. @PrivateProperty remains on emailKey and fullNameKey only.

MongoDB Polymorphic Types

  • Prefer regular classes over data classes for MongoDB-persisted polymorphic types: Spring Data resolves subtypes via _class natively when subtypes are regular classes with var properties (no-arg constructor). Kotlin data classes lack no-arg constructor, forcing custom ReadingConverter/WritingConverter. Integration, ExternalEntity, LLMCompletionOptions all use regular classes. Response still uses converters (legacy).

Localization

  • Use LanguageCode.code (lowercase: "en", "el") not .name (uppercase: "EN", "EL") when indexing Localized<T> maps: Localized<T> keys are lowercase. .name silently falls through to fallback (.values.first()), masking the bug. FileUploadNode has a pre-existing .name bug on develop.

Bot Content Manager

  • BotContentManagerImpl has 3 when(node) blocks for i18n: New FlowGraphNode types with custom Localized<> fields must be added to all three: (1) trimActivityLanguages, (2) language detection in rewriteContentLanguage, (3) language remapping in rewriteContentLanguage. Non-nullable fields use remapOrEmpty(), nullable use remap().

Field Sync with hbf-core-api

  • Adding a field to hbf-core-api types requires a matching field in hbf-core Kotlin models: Spring Data MongoDB silently drops fields not in the Kotlin model during deserialization. hbf-bot fetches through hbf-core REST API, not direct MongoDB.

Knowledge Base API

  • fetchKnowledgeBaseArticles (list endpoint) returns article body unconditionally. There is no includeBody parameter in OrganizationKnowledgeBaseArticleResource.kt. The content set (which contains body) is always mapped in KnowledgeBaseArticleMapper.toDto(). The frontend's urlParams: { includeBody: true } on single-article fetches is a no-op — the backend ignores unknown query params. Use the list endpoint with pageSize: 5000 to get all articles with bodies in a single call.