Files
Stirling-PDF/app
Connor Yoh 6eb41b6931 payg(c4): annotate AI controllers + tag InternalApiClient sub-steps as AUTOMATION
The saas PaygChargeInterceptor classifies a request as AI / AUTOMATION /
API / BYPASSED using a fixed precedence: X-Stirling-Automation header >
@RequiresFeature(AUTOMATION) > @RequiresFeature(AI_SUPPORT) > API-key
auth > BYPASSED (manual UI).

Plug the AI surface and the automation sub-step path:

AI controllers (saas → easy import):
- AiCreateController, AiCreateInternalController, AiProxyController each
  get class-level @RequiresFeature(AI_SUPPORT). The interceptor already
  falls back to the bean type via AnnotationUtils.findAnnotation when no
  method-level annotation is present.

Automation sub-step header (InternalApiClient in common):
- Every caller of InternalApiClient.post() is a parent automation flow
  (PipelineProcessor, AiWorkflowService, PolicyExecutor) running a child
  tool via loopback HTTP. Tag every dispatch with
  X-Stirling-Automation: true so the child step bills as AUTOMATION
  regardless of its own annotation — i.e. an AI-OCR step inside a
  policy run is correctly billed AUTOMATION rather than AI.

Deviation (documented in test javadoc): PipelineController lives in
core and PolicyController lives in proprietary. Neither module can
import @RequiresFeature from saas without a forbidden upward dependency
(both build under STIRLING_FLAVOR=core/proprietary where saas is
absent). Promoting RequiresFeature + FeatureGate to common is a
non-trivial refactor (touches 18 files across multiple C-bucket
commits) and out of scope for C4. The X-Stirling-Automation header
covers sub-step dispatch via InternalApiClient; direct user-facing
calls to /api/v1/pipeline/handleData therefore bill as BYPASSED (WEB)
or API (api-key auth) rather than AUTOMATION. Annotating those
controllers is left to a future refactor that promotes the cap types
to common.

Tests:
- RequiresFeatureAnnotationRolloutTest pins the AI controller
  classifications so a refactor can't silently regress to BYPASSED.
- InternalApiClientTest.postTagsRequestAsAutomation captures the
  HttpHeaders submitted to RestTemplate and asserts the marker.
2026-06-09 14:48:36 +01:00
..
2026-06-08 10:50:55 +00:00
2026-06-08 10:50:55 +00:00