Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .agents/journal/bolt.md
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.cvix.resume.domain.TemplateMetadata
import com.cvix.resume.domain.TemplateSourceStrategy
import com.cvix.subscription.domain.SubscriptionTier
import org.slf4j.LoggerFactory
import org.springframework.cache.annotation.Cacheable

/**
* Catalog service for managing and retrieving template metadata.
Expand Down Expand Up @@ -44,6 +45,9 @@ class TemplateCatalog(private val templateSourceStrategy: TemplateSourceStrategy
* @param limit Maximum number of templates to return (null = no limit)
* @return List of template metadata from all active sources, filtered by subscription tier
*/
// Performance: Cache results to avoid repeated scanning of template repositories.
// Keyed by tier and limit as these are the primary filter criteria.
@Cacheable(value = ["templates"], key = "#subscriptionTier.toString() + '-' + (#limit ?: -1)")
suspend fun listTemplates(
subscriptionTier: SubscriptionTier,
limit: Int?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.cvix.resume.domain.exception.TemplateNotFoundException
import com.cvix.subscription.domain.SubscriptionTier
import java.util.UUID
import org.slf4j.LoggerFactory
import org.springframework.cache.annotation.Cacheable

/**
* Service for finding and validating template access.
Expand Down Expand Up @@ -37,6 +38,9 @@ class TemplateFinder(
* @throws TemplateNotFoundException if template not found in any active repository
* @throws TemplateAccessDeniedException if user lacks required subscription tier
*/
// Performance: Cache template details and access validation results.
// Keyed by template and tier; userId is excluded as access is strictly tier-based.
@Cacheable(value = ["template-details"], key = "#templateId + '-' + #userTier.toString()")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟑 Minor

userId parameter is invisible to the cache but changes method semantics for logging/audit.

Since userId is excluded from the cache key (correctly, for access logic), cache hits will skip the entire method body including all log.debug/log.warn statements. This means you lose the audit trail of who accessed which template once the result is cached. If that audit trail matters for compliance or debugging, consider adding a log statement in the calling layer or using a cache event listener.

πŸ€– Prompt for AI Agents
In
`@server/modules/resume/resume-application/src/main/kotlin/com/cvix/resume/application/template/TemplateFinder.kt`
at line 43, The cache annotation on TemplateFinder (the method with
`@Cacheable`(value = ["template-details"], key = "#templateId + '-' +
`#userTier.toString`()") ) causes cached hits to skip the method body and thus
skip any userId audit logs; fix by moving the audit logging out of the cached
method: create a small non-cached wrapper (e.g.
TemplateFinder.logAndFindTemplate or a calling-layer method) that accepts
templateId, userTier, userId, writes the audit log (log.debug/log.warn with
userId/templateId/tier) and then calls the existing cached method (the
`@Cacheable` method) to fetch the template; alternatively, if you prefer not to
add a wrapper, implement a cache event listener that records access events with
user context, but the wrapper approach is simplest and recommended.

suspend fun findByIdAndValidateAccess(
templateId: String,
userId: UUID,
Expand Down
Loading