发布

  • [OPIK-6409] [BE] feat: add V1 workspace allowlist (#6631)

    frostbyte_neo 发布于 2026-05-08 13:02:18 +00:00

    • [OPIK-6409] [BE] feat: add v1WorkspaceAllowlist config + service short-circuit

    Symmetric counterpart of the existing v2WorkspaceAllowlist: a comma-separated
    list of workspace IDs that always resolve to version_1, short-circuiting
    cache, auth gate, entity check, and fallback. Use case is customer-driven V1
    stickiness — pinning specific workspaces to legacy navigation without the
    deployment-wide impact of TOGGLE_FORCE_WORKSPACE_VERSION.

    • ServiceTogglesConfig: new v1WorkspaceAllowlistIds Set + @JsonSetter, parsed
      identically to its V2 sibling. The two setters now share a private
      parseAllowlist helper (comma-split, strip whitespace, filter blanks,
      unmodifiable).
    • config.yml: new v1WorkspaceAllowlist key reading TOGGLE_V1_WORKSPACE_ALLOWLIST
      with the same operational notes as the V2 entry, slotted between v2WorkspaceAllowlist
      and forceWorkspaceVersion. Both v2WorkspaceAllowlist and forceWorkspaceVersion
      comments updated to reflect the new priority order (V2 > V1 > force-version).
    • AbstractWorkspaceVersionService.getWorkspaceVersion: V1 allowlist short-circuit
      inserted immediately after the V2 allowlist check and before getForcedVersion();
      emits an info log on hit mirroring the V2 message. The constructor now logs a
      one-time warn at startup when any workspace ID appears in both lists (V2 wins,
      per the priority order — but operators should know).

    Allowlist hits return before reaching computeVersion/persistAndEmit, so no
    workspaces-table write or workspace_version_determined analytics event is
    emitted on a hit (matches the V2 allowlist behaviour).

    • [OPIK-6409] [BE] test: V1WorkspaceAllowlistTest covering positive/miss/precedence

    Mirrors V2WorkspaceAllowlistTest. Single nested class drives the full priority
    matrix in one parameterized test:

    • V1 allowlist hit on V1_ALLOWLISTED_ID_1 / V1_ALLOWLISTED_ID_2 → version_1,
      even though forceWorkspaceVersion=version_2 is set globally
      (proves the V1 allowlist wins over the force-version override).
    • Workspace ID present in BOTH allowlists → version_2
      (proves the V2 allowlist wins over the V1 allowlist on overlap).
    • Random non-allowlisted workspace → version_2 via forceWorkspaceVersion
      (proves the miss path falls through to the next priority step).

    Plus a focused v1AllowlistHit__doesNotPersistRowToWorkspacesTable test that
    asserts findById returns empty after a V1 allowlist hit, confirming the
    short-circuit happens before persistAndEmit reaches the workspaces table.

    • [OPIK-6409] [BE] refactor: inline single-flip helper, drop SELECT FOR UPDATE on version

    Per Andrés's review on the OPIK-4933 PR (carried over here on rebase):

    • Inline markFirstTraceReported and markMigrationSkipped. Each method now
      owns its full UPDATE → INSERT → retry-UPDATE flow; the shared
      transitionFlagAtomically helper and isDuplicateKeyViolation predicate
      are removed. Methods can evolve independently (SRP).
    • Drop upsertVersionAndReturnPrevious and the DAO's findVersionForUpdate.
      Restore the prior findById + upsertVersion pair in persistAndEmitBlocking.
      Acceptable per the review: this signal feeds analytics where full precision
      is not required.
    下载附件