@pipeline-builder/api-server 3.4.130 → 3.4.132

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,7 +40,11 @@ export function withRoute(handler, options = {}) {
40
40
  const { requireOrgId = true } = options;
41
41
  return async (req, res) => {
42
42
  const ctx = getContext(req);
43
- const orgId = ctx.identity.orgId?.toLowerCase() || '';
43
+ // `identity.orgId` is already normalized (trimmed + lowercased) once at
44
+ // resolution in api-core's `getIdentity`, so the previously-duplicated
45
+ // `.toLowerCase()` here is redundant — kept normalization at the single
46
+ // source of truth instead. This value now matches the RLS GUC exactly.
47
+ const orgId = ctx.identity.orgId || '';
44
48
  const userId = ctx.identity.userId || '';
45
49
  if (requireOrgId && !orgId) {
46
50
  return sendBadRequest(res, 'Organization ID is required');
@@ -77,4 +81,4 @@ export function withRoute(handler, options = {}) {
77
81
  }
78
82
  };
79
83
  }
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtd3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvcm91dGUtd3JhcHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsWUFBWSxFQUNaLGNBQWMsRUFDZCxTQUFTLEVBQ1QsY0FBYyxFQUNkLGlCQUFpQixFQUNqQixZQUFZLEdBQ2IsTUFBTSw0QkFBNEIsQ0FBQztBQUVwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFHOUMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRTdDOzs7OztHQUtHO0FBQ0gsU0FBUyxlQUFlLENBQUMsS0FBYztJQUNyQyxJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUN4RSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxtQkFBbUIseUJBQXlCLENBQUM7SUFDdkUsQ0FBQztJQUNELE9BQU8sWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUE4QkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FDdkIsT0FBNEMsRUFDNUMsT0FBTyxHQUFxQixFQUFFO0lBRTlCLE1BQU0sRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRXhDLE9BQU8sS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtRQUMzQyxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUIsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO1FBQ3RELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUV6QyxJQUFJLFlBQVksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLE9BQU8sY0FBYyxDQUFDLEdBQUcsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFFRCxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Ysc0RBQXNEO1lBQ3RELElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNwQixNQUFNLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxFQUFFO29CQUN0RCxTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVM7b0JBQ3hCLEtBQUssRUFBRSxlQUFlLENBQUMsS0FBSyxDQUFDO2lCQUM5QixDQUFDLENBQUM7Z0JBQ0gsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLEtBQUssWUFBWSxRQUFRLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLFVBQVUsSUFBSSxHQUFHLElBQUksS0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHO29CQUM5RCxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVU7b0JBQ2xCLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQ1IsT0FBTyxTQUFTLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzRCxDQUFDO1lBRUQsNkVBQTZFO1lBQzdFLDhFQUE4RTtZQUM5RSwrRUFBK0U7WUFDL0UsOEVBQThFO1lBQzlFLE1BQU0sRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRTtnQkFDakMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTO2dCQUN4QixLQUFLLEVBQUUsZUFBZSxDQUFDLEtBQUssQ0FBQztnQkFDN0IsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDMUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsdUJBQXVCLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDdkYsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHtcbiAgQXBwRXJyb3IsXG4gIGVycm9yTWVzc2FnZSxcbiAgZXh0cmFjdERiRXJyb3IsXG4gIHNlbmRFcnJvcixcbiAgc2VuZEJhZFJlcXVlc3QsXG4gIHNlbmRJbnRlcm5hbEVycm9yLFxuICBjcmVhdGVMb2dnZXIsXG59IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIFJlcXVlc3RIYW5kbGVyIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSAnLi9nZXQtY29udGV4dC5qcyc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3RDb250ZXh0IH0gZnJvbSAnLi9yZXF1ZXN0LXR5cGVzLmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyb3V0ZS13cmFwcGVyJyk7XG5cbi8qKlxuICogQSBsb2ctc2FmZSByZW5kZXJpbmcgb2YgYW4gdW5rbm93biBlcnJvci4gZHJpenpsZS1vcm0ncyBgRHJpenpsZVF1ZXJ5RXJyb3JgXG4gKiBlbWJlZHMgdGhlIGZhaWxlZCBTUUwgc3RhdGVtZW50IEFORCB0aGUgYm91bmQgcGFyYW1ldGVyIHZhbHVlcyAocmVhbCBkYXRhKSBpblxuICogaXRzIGAubWVzc2FnZWAgKGBGYWlsZWQgcXVlcnk6IDxzcWw+XFxucGFyYW1zOiA8dmFsdWVzPmApLiBOZXZlciBwdXQgdGhhdCBpbiBhXG4gKiByZXNwb25zZSBvciBhIGxvZyBsaW5lIOKAlCBjb2xsYXBzZSBpdCB0byB0aGUgZXJyb3IgbmFtZS4gT3RoZXIgZXJyb3JzIGFyZSBzYWZlLlxuICovXG5mdW5jdGlvbiBzYWZlRXJyb3JGb3JMb2coZXJyb3I6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlLnN0YXJ0c1dpdGgoJ0ZhaWxlZCBxdWVyeTonKSkge1xuICAgIHJldHVybiBgJHtlcnJvci5uYW1lIHx8ICdEcml6emxlUXVlcnlFcnJvcid9OiBkYXRhYmFzZSBxdWVyeSBmYWlsZWRgO1xuICB9XG4gIHJldHVybiBlcnJvck1lc3NhZ2UoZXJyb3IpO1xufVxuXG4vKipcbiAqIENvbnRleHQgb2JqZWN0IHBhc3NlZCB0byBldmVyeSByb3V0ZSBoYW5kbGVyIHdyYXBwZWQgd2l0aCBgd2l0aFJvdXRlKClgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlQ29udGV4dCB7XG4gIC8qKiBPcmlnaW5hbCBFeHByZXNzIHJlcXVlc3QgKi9cbiAgcmVxOiBSZXF1ZXN0O1xuICAvKiogT3JpZ2luYWwgRXhwcmVzcyByZXNwb25zZSAqL1xuICByZXM6IFJlc3BvbnNlO1xuICAvKiogUmVxdWVzdCBjb250ZXh0IHdpdGggaWRlbnRpdHkgYW5kIGxvZ2dpbmcgKi9cbiAgY3R4OiBSZXF1ZXN0Q29udGV4dDtcbiAgLyoqIExvd2VyY2FzZWQgb3JnYW5pemF0aW9uIElEIChndWFyYW50ZWVkIG5vbi1lbXB0eSB3aGVuIHJlcXVpcmVPcmdJZCBpcyB0cnVlKSAqL1xuICBvcmdJZDogc3RyaW5nO1xuICAvKiogVXNlciBJRCBmcm9tIEpXVCAoZGVmYXVsdHMgdG8gZW1wdHkgc3RyaW5nKSAqL1xuICB1c2VySWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgd2l0aFJvdXRlKClgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdpdGhSb3V0ZU9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciB0byByZXF1aXJlIG9yZ0lkIG9uIHRoZSByZXF1ZXN0LlxuICAgKiBXaGVuIHRydWUgKGRlZmF1bHQpLCByZXR1cm5zIDQwMCBpZiBvcmdJZCBpcyBtaXNzaW5nLlxuICAgKiBTZXQgdG8gZmFsc2UgZm9yIHJvdXRlcyB0aGF0IGRvbid0IG5lZWQgb3JnIGNvbnRleHQuXG4gICAqL1xuICByZXF1aXJlT3JnSWQ/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFdyYXAgYW4gYXN5bmMgcm91dGUgaGFuZGxlciB3aXRoIHN0YW5kYXJkIGJvaWxlcnBsYXRlLlxuICpcbiAqIEV4dHJhY3RzIGNvbnRleHQsIG9yZ0lkLCB1c2VySWQgZnJvbSB0aGUgcmVxdWVzdCwgdmFsaWRhdGVzIG9yZ0lkLFxuICogYW5kIGNhdGNoZXMgZXJyb3JzLiBUeXBlZCBgQXBwRXJyb3JgIHN1YmNsYXNzZXMgYXJlIGF1dG9tYXRpY2FsbHlcbiAqIG1hcHBlZCB0byB0aGUgY29ycmVjdCBIVFRQIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSBoYW5kbGVyIC0gQXN5bmMgZnVuY3Rpb24gcmVjZWl2aW5nIGEgUm91dGVDb250ZXh0XG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICogQHJldHVybnMgRXhwcmVzcyBSZXF1ZXN0SGFuZGxlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByb3V0ZXIuZ2V0KCcvOmlkJywgd2l0aFJvdXRlKGFzeW5jICh7IHJlcSwgcmVzLCBjdHgsIG9yZ0lkIH0pID0+IHtcbiAqICAgY29uc3QgaWQgPSBnZXRQYXJhbShyZXEucGFyYW1zLCAnaWQnKTtcbiAqICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcGlwZWxpbmVTZXJ2aWNlLmZpbmRCeUlkKGlkLCBvcmdJZCk7XG4gKiAgIGlmICghcmVzdWx0KSB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcignUGlwZWxpbmUgbm90IGZvdW5kJyk7XG4gKiAgIHJldHVybiBzZW5kU3VjY2VzcyhyZXMsIDIwMCwgeyBwaXBlbGluZTogcmVzdWx0IH0pO1xuICogfSkpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUm91dGUoXG4gIGhhbmRsZXI6IChyYzogUm91dGVDb250ZXh0KSA9PiBQcm9taXNlPHZvaWQ+LFxuICBvcHRpb25zOiBXaXRoUm91dGVPcHRpb25zID0ge30sXG4pOiBSZXF1ZXN0SGFuZGxlciB7XG4gIGNvbnN0IHsgcmVxdWlyZU9yZ0lkID0gdHJ1ZSB9ID0gb3B0aW9ucztcblxuICByZXR1cm4gYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIGNvbnN0IGN0eCA9IGdldENvbnRleHQocmVxKTtcbiAgICBjb25zdCBvcmdJZCA9IGN0eC5pZGVudGl0eS5vcmdJZD8udG9Mb3dlckNhc2UoKSB8fCAnJztcbiAgICBjb25zdCB1c2VySWQgPSBjdHguaWRlbnRpdHkudXNlcklkIHx8ICcnO1xuXG4gICAgaWYgKHJlcXVpcmVPcmdJZCAmJiAhb3JnSWQpIHtcbiAgICAgIHJldHVybiBzZW5kQmFkUmVxdWVzdChyZXMsICdPcmdhbml6YXRpb24gSUQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgaGFuZGxlcih7IHJlcSwgcmVzLCBjdHgsIG9yZ0lkLCB1c2VySWQgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIERvbid0IHNlbmQgYW5vdGhlciByZXNwb25zZSBpZiBvbmUgd2FzIGFscmVhZHkgc2VudFxuICAgICAgaWYgKHJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ1JvdXRlIGhhbmRsZXIgZXJyb3IgYWZ0ZXIgcmVzcG9uc2Ugc2VudCcsIHtcbiAgICAgICAgICByZXF1ZXN0SWQ6IGN0eC5yZXF1ZXN0SWQsXG4gICAgICAgICAgZXJyb3I6IHNhZmVFcnJvckZvckxvZyhlcnJvciksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEFwcEVycm9yKSB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGVycm9yLnN0YXR1c0NvZGUgPj0gNDAwICYmIGVycm9yLnN0YXR1c0NvZGUgPCA2MDBcbiAgICAgICAgICA/IGVycm9yLnN0YXR1c0NvZGVcbiAgICAgICAgICA6IDUwMDtcbiAgICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIHN0YXR1cywgZXJyb3IubWVzc2FnZSwgZXJyb3IuY29kZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFVuaGFuZGxlZCBlcnJvciDihpIgNTAwLiBORVZFUiBlY2hvIHRoZSByYXcgbWVzc2FnZSB0byB0aGUgY2xpZW50OiBEQiBkcml2ZXJcbiAgICAgIC8vIGVycm9ycyBjYXJyeSB0aGUgU1FMICsgYm91bmQgcGFyYW1zLCBhbmQgQ3J1ZFNlcnZpY2UgZGVsaWJlcmF0ZWx5IGxldHMgdGhlbVxuICAgICAgLy8gcHJvcGFnYXRlIGhlcmUuIFNlbmQgYSBnZW5lcmljIG1lc3NhZ2UgKyByZXF1ZXN0SWQgKHRvIGNvcnJlbGF0ZSB3aXRoIGxvZ3MpLFxuICAgICAgLy8gYW5kIGxvZyBvbmx5IHNhbml0aXplZCBEQiBtZXRhZGF0YSAoY29kZS9jb25zdHJhaW50L3RhYmxlIOKAlCBubyBTUUwvcGFyYW1zKS5cbiAgICAgIGNvbnN0IGRiID0gZXh0cmFjdERiRXJyb3IoZXJyb3IpO1xuICAgICAgY3R4LmxvZygnRVJST1InLCAnUmVxdWVzdCBmYWlsZWQnLCB7XG4gICAgICAgIHJlcXVlc3RJZDogY3R4LnJlcXVlc3RJZCxcbiAgICAgICAgZXJyb3I6IHNhZmVFcnJvckZvckxvZyhlcnJvciksXG4gICAgICAgIC4uLihPYmplY3Qua2V5cyhkYikubGVuZ3RoID8geyBkYiB9IDoge30pLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gc2VuZEludGVybmFsRXJyb3IocmVzLCAnSW50ZXJuYWwgc2VydmVyIGVycm9yJywgeyByZXF1ZXN0SWQ6IGN0eC5yZXF1ZXN0SWQgfSk7XG4gICAgfVxuICB9O1xufVxuIl19
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtd3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvcm91dGUtd3JhcHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsWUFBWSxFQUNaLGNBQWMsRUFDZCxTQUFTLEVBQ1QsY0FBYyxFQUNkLGlCQUFpQixFQUNqQixZQUFZLEdBQ2IsTUFBTSw0QkFBNEIsQ0FBQztBQUVwQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFHOUMsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRTdDOzs7OztHQUtHO0FBQ0gsU0FBUyxlQUFlLENBQUMsS0FBYztJQUNyQyxJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUN4RSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxtQkFBbUIseUJBQXlCLENBQUM7SUFDdkUsQ0FBQztJQUNELE9BQU8sWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUE4QkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FDdkIsT0FBNEMsRUFDNUMsT0FBTyxHQUFxQixFQUFFO0lBRTlCLE1BQU0sRUFBRSxZQUFZLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRXhDLE9BQU8sS0FBSyxFQUFFLEdBQVksRUFBRSxHQUFhLEVBQUUsRUFBRTtRQUMzQyxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUIsd0VBQXdFO1FBQ3hFLHVFQUF1RTtRQUN2RSx3RUFBd0U7UUFDeEUsdUVBQXVFO1FBQ3ZFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN2QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFFekMsSUFBSSxZQUFZLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMzQixPQUFPLGNBQWMsQ0FBQyxHQUFHLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztRQUM1RCxDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLHNEQUFzRDtZQUN0RCxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsRUFBRTtvQkFDdEQsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTO29CQUN4QixLQUFLLEVBQUUsZUFBZSxDQUFDLEtBQUssQ0FBQztpQkFDOUIsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxLQUFLLFlBQVksUUFBUSxFQUFFLENBQUM7Z0JBQzlCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksR0FBRyxJQUFJLEtBQUssQ0FBQyxVQUFVLEdBQUcsR0FBRztvQkFDOUQsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVO29CQUNsQixDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUNSLE9BQU8sU0FBUyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0QsQ0FBQztZQUVELDZFQUE2RTtZQUM3RSw4RUFBOEU7WUFDOUUsK0VBQStFO1lBQy9FLDhFQUE4RTtZQUM5RSxNQUFNLEVBQUUsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBQ2pDLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBUztnQkFDeEIsS0FBSyxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUM7Z0JBQzdCLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQzFDLENBQUMsQ0FBQztZQUNILE9BQU8saUJBQWlCLENBQUMsR0FBRyxFQUFFLHVCQUF1QixFQUFFLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7XG4gIEFwcEVycm9yLFxuICBlcnJvck1lc3NhZ2UsXG4gIGV4dHJhY3REYkVycm9yLFxuICBzZW5kRXJyb3IsXG4gIHNlbmRCYWRSZXF1ZXN0LFxuICBzZW5kSW50ZXJuYWxFcnJvcixcbiAgY3JlYXRlTG9nZ2VyLFxufSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBSZXF1ZXN0SGFuZGxlciB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0Q29udGV4dCB9IGZyb20gJy4vcmVxdWVzdC10eXBlcy5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncm91dGUtd3JhcHBlcicpO1xuXG4vKipcbiAqIEEgbG9nLXNhZmUgcmVuZGVyaW5nIG9mIGFuIHVua25vd24gZXJyb3IuIGRyaXp6bGUtb3JtJ3MgYERyaXp6bGVRdWVyeUVycm9yYFxuICogZW1iZWRzIHRoZSBmYWlsZWQgU1FMIHN0YXRlbWVudCBBTkQgdGhlIGJvdW5kIHBhcmFtZXRlciB2YWx1ZXMgKHJlYWwgZGF0YSkgaW5cbiAqIGl0cyBgLm1lc3NhZ2VgIChgRmFpbGVkIHF1ZXJ5OiA8c3FsPlxcbnBhcmFtczogPHZhbHVlcz5gKS4gTmV2ZXIgcHV0IHRoYXQgaW4gYVxuICogcmVzcG9uc2Ugb3IgYSBsb2cgbGluZSDigJQgY29sbGFwc2UgaXQgdG8gdGhlIGVycm9yIG5hbWUuIE90aGVyIGVycm9ycyBhcmUgc2FmZS5cbiAqL1xuZnVuY3Rpb24gc2FmZUVycm9yRm9yTG9nKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5zdGFydHNXaXRoKCdGYWlsZWQgcXVlcnk6JykpIHtcbiAgICByZXR1cm4gYCR7ZXJyb3IubmFtZSB8fCAnRHJpenpsZVF1ZXJ5RXJyb3InfTogZGF0YWJhc2UgcXVlcnkgZmFpbGVkYDtcbiAgfVxuICByZXR1cm4gZXJyb3JNZXNzYWdlKGVycm9yKTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IG9iamVjdCBwYXNzZWQgdG8gZXZlcnkgcm91dGUgaGFuZGxlciB3cmFwcGVkIHdpdGggYHdpdGhSb3V0ZSgpYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSb3V0ZUNvbnRleHQge1xuICAvKiogT3JpZ2luYWwgRXhwcmVzcyByZXF1ZXN0ICovXG4gIHJlcTogUmVxdWVzdDtcbiAgLyoqIE9yaWdpbmFsIEV4cHJlc3MgcmVzcG9uc2UgKi9cbiAgcmVzOiBSZXNwb25zZTtcbiAgLyoqIFJlcXVlc3QgY29udGV4dCB3aXRoIGlkZW50aXR5IGFuZCBsb2dnaW5nICovXG4gIGN0eDogUmVxdWVzdENvbnRleHQ7XG4gIC8qKiBMb3dlcmNhc2VkIG9yZ2FuaXphdGlvbiBJRCAoZ3VhcmFudGVlZCBub24tZW1wdHkgd2hlbiByZXF1aXJlT3JnSWQgaXMgdHJ1ZSkgKi9cbiAgb3JnSWQ6IHN0cmluZztcbiAgLyoqIFVzZXIgSUQgZnJvbSBKV1QgKGRlZmF1bHRzIHRvIGVtcHR5IHN0cmluZykgKi9cbiAgdXNlcklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYHdpdGhSb3V0ZSgpYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXaXRoUm91dGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVxdWlyZSBvcmdJZCBvbiB0aGUgcmVxdWVzdC5cbiAgICogV2hlbiB0cnVlIChkZWZhdWx0KSwgcmV0dXJucyA0MDAgaWYgb3JnSWQgaXMgbWlzc2luZy5cbiAgICogU2V0IHRvIGZhbHNlIGZvciByb3V0ZXMgdGhhdCBkb24ndCBuZWVkIG9yZyBjb250ZXh0LlxuICAgKi9cbiAgcmVxdWlyZU9yZ0lkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXcmFwIGFuIGFzeW5jIHJvdXRlIGhhbmRsZXIgd2l0aCBzdGFuZGFyZCBib2lsZXJwbGF0ZS5cbiAqXG4gKiBFeHRyYWN0cyBjb250ZXh0LCBvcmdJZCwgdXNlcklkIGZyb20gdGhlIHJlcXVlc3QsIHZhbGlkYXRlcyBvcmdJZCxcbiAqIGFuZCBjYXRjaGVzIGVycm9ycy4gVHlwZWQgYEFwcEVycm9yYCBzdWJjbGFzc2VzIGFyZSBhdXRvbWF0aWNhbGx5XG4gKiBtYXBwZWQgdG8gdGhlIGNvcnJlY3QgSFRUUCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0gaGFuZGxlciAtIEFzeW5jIGZ1bmN0aW9uIHJlY2VpdmluZyBhIFJvdXRlQ29udGV4dFxuICogQHBhcmFtIG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIG9wdGlvbnNcbiAqIEByZXR1cm5zIEV4cHJlc3MgUmVxdWVzdEhhbmRsZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcm91dGVyLmdldCgnLzppZCcsIHdpdGhSb3V0ZShhc3luYyAoeyByZXEsIHJlcywgY3R4LCBvcmdJZCB9KSA9PiB7XG4gKiAgIGNvbnN0IGlkID0gZ2V0UGFyYW0ocmVxLnBhcmFtcywgJ2lkJyk7XG4gKiAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBpcGVsaW5lU2VydmljZS5maW5kQnlJZChpZCwgb3JnSWQpO1xuICogICBpZiAoIXJlc3VsdCkgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoJ1BpcGVsaW5lIG5vdCBmb3VuZCcpO1xuICogICByZXR1cm4gc2VuZFN1Y2Nlc3MocmVzLCAyMDAsIHsgcGlwZWxpbmU6IHJlc3VsdCB9KTtcbiAqIH0pKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aFJvdXRlKFxuICBoYW5kbGVyOiAocmM6IFJvdXRlQ29udGV4dCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgb3B0aW9uczogV2l0aFJvdXRlT3B0aW9ucyA9IHt9LFxuKTogUmVxdWVzdEhhbmRsZXIge1xuICBjb25zdCB7IHJlcXVpcmVPcmdJZCA9IHRydWUgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UpID0+IHtcbiAgICBjb25zdCBjdHggPSBnZXRDb250ZXh0KHJlcSk7XG4gICAgLy8gYGlkZW50aXR5Lm9yZ0lkYCBpcyBhbHJlYWR5IG5vcm1hbGl6ZWQgKHRyaW1tZWQgKyBsb3dlcmNhc2VkKSBvbmNlIGF0XG4gICAgLy8gcmVzb2x1dGlvbiBpbiBhcGktY29yZSdzIGBnZXRJZGVudGl0eWAsIHNvIHRoZSBwcmV2aW91c2x5LWR1cGxpY2F0ZWRcbiAgICAvLyBgLnRvTG93ZXJDYXNlKClgIGhlcmUgaXMgcmVkdW5kYW50IOKAlCBrZXB0IG5vcm1hbGl6YXRpb24gYXQgdGhlIHNpbmdsZVxuICAgIC8vIHNvdXJjZSBvZiB0cnV0aCBpbnN0ZWFkLiBUaGlzIHZhbHVlIG5vdyBtYXRjaGVzIHRoZSBSTFMgR1VDIGV4YWN0bHkuXG4gICAgY29uc3Qgb3JnSWQgPSBjdHguaWRlbnRpdHkub3JnSWQgfHwgJyc7XG4gICAgY29uc3QgdXNlcklkID0gY3R4LmlkZW50aXR5LnVzZXJJZCB8fCAnJztcblxuICAgIGlmIChyZXF1aXJlT3JnSWQgJiYgIW9yZ0lkKSB7XG4gICAgICByZXR1cm4gc2VuZEJhZFJlcXVlc3QocmVzLCAnT3JnYW5pemF0aW9uIElEIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGhhbmRsZXIoeyByZXEsIHJlcywgY3R4LCBvcmdJZCwgdXNlcklkIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBEb24ndCBzZW5kIGFub3RoZXIgcmVzcG9uc2UgaWYgb25lIHdhcyBhbHJlYWR5IHNlbnRcbiAgICAgIGlmIChyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdSb3V0ZSBoYW5kbGVyIGVycm9yIGFmdGVyIHJlc3BvbnNlIHNlbnQnLCB7XG4gICAgICAgICAgcmVxdWVzdElkOiBjdHgucmVxdWVzdElkLFxuICAgICAgICAgIGVycm9yOiBzYWZlRXJyb3JGb3JMb2coZXJyb3IpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBcHBFcnJvcikge1xuICAgICAgICBjb25zdCBzdGF0dXMgPSBlcnJvci5zdGF0dXNDb2RlID49IDQwMCAmJiBlcnJvci5zdGF0dXNDb2RlIDwgNjAwXG4gICAgICAgICAgPyBlcnJvci5zdGF0dXNDb2RlXG4gICAgICAgICAgOiA1MDA7XG4gICAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBzdGF0dXMsIGVycm9yLm1lc3NhZ2UsIGVycm9yLmNvZGUpO1xuICAgICAgfVxuXG4gICAgICAvLyBVbmhhbmRsZWQgZXJyb3Ig4oaSIDUwMC4gTkVWRVIgZWNobyB0aGUgcmF3IG1lc3NhZ2UgdG8gdGhlIGNsaWVudDogREIgZHJpdmVyXG4gICAgICAvLyBlcnJvcnMgY2FycnkgdGhlIFNRTCArIGJvdW5kIHBhcmFtcywgYW5kIENydWRTZXJ2aWNlIGRlbGliZXJhdGVseSBsZXRzIHRoZW1cbiAgICAgIC8vIHByb3BhZ2F0ZSBoZXJlLiBTZW5kIGEgZ2VuZXJpYyBtZXNzYWdlICsgcmVxdWVzdElkICh0byBjb3JyZWxhdGUgd2l0aCBsb2dzKSxcbiAgICAgIC8vIGFuZCBsb2cgb25seSBzYW5pdGl6ZWQgREIgbWV0YWRhdGEgKGNvZGUvY29uc3RyYWludC90YWJsZSDigJQgbm8gU1FML3BhcmFtcykuXG4gICAgICBjb25zdCBkYiA9IGV4dHJhY3REYkVycm9yKGVycm9yKTtcbiAgICAgIGN0eC5sb2coJ0VSUk9SJywgJ1JlcXVlc3QgZmFpbGVkJywge1xuICAgICAgICByZXF1ZXN0SWQ6IGN0eC5yZXF1ZXN0SWQsXG4gICAgICAgIGVycm9yOiBzYWZlRXJyb3JGb3JMb2coZXJyb3IpLFxuICAgICAgICAuLi4oT2JqZWN0LmtleXMoZGIpLmxlbmd0aCA/IHsgZGIgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNlbmRJbnRlcm5hbEVycm9yKHJlcywgJ0ludGVybmFsIHNlcnZlciBlcnJvcicsIHsgcmVxdWVzdElkOiBjdHgucmVxdWVzdElkIH0pO1xuICAgIH1cbiAgfTtcbn1cbiJdfQ==
@@ -7,6 +7,9 @@ import { getContext } from './get-context.js';
7
7
  * the active-org parent (org → team hierarchy) so downstream side-effects can
8
8
  * reach it without a request. */
9
9
  const identityScope = (req) => ({
10
+ // `identity.orgId` is already normalized (trimmed + lowercased) once at
11
+ // resolution in api-core's `getIdentity`, so the GUC set here matches the
12
+ // app-layer WHERE clauses exactly — no ad-hoc re-normalization needed.
10
13
  orgId: getContext(req).identity.orgId,
11
14
  isSuperAdmin: isSystemAdmin(req),
12
15
  parentOrgId: req.user?.parentOrganizationId,
@@ -40,4 +43,4 @@ export function withTenantContext(resolve = identityScope) {
40
43
  runWithTenantContext(scope, () => next());
41
44
  };
42
45
  }
43
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3RlbmFudC1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxpQ0FBaUMsQ0FBQztBQUUzRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFZOUM7O2tDQUVrQztBQUNsQyxNQUFNLGFBQWEsR0FBd0IsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkQsS0FBSyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztJQUNyQyxZQUFZLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQztJQUNoQyxXQUFXLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxvQkFBb0I7Q0FDNUMsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLE9BQU8sR0FBd0IsYUFBYTtJQUM1RSxPQUFPLENBQUMsR0FBWSxFQUFFLElBQWMsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDaEUsSUFBSSxLQUFvQixDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUNELG9CQUFvQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgaXNTeXN0ZW1BZG1pbiB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHJ1bldpdGhUZW5hbnRDb250ZXh0LCB0eXBlIFRlbmFudENvbnRleHQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1kYXRhJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBSTFMgdGVuYW50IHNjb3BlIGZvciBhIHJlcXVlc3QuIFRoZSBkZWZhdWx0IHJlYWRzIHRoZSBDQUxMRVInc1xuICogYXV0aGVudGljYXRlZCBpZGVudGl0eSBvcmcgKGBjdHguaWRlbnRpdHkub3JnSWRgLCB2YWxpZGF0ZWQgYnkgcmVxdWlyZU9yZ0lkKSDigJQgTk9UXG4gKiBgZ2V0T3JnSWQocmVxKWAsIHdoaWNoIHByZWZlcnMgcm91dGUgcGFyYW1zICh0aGUgcXVlcmllZCBzY29wZSksIHRoZSB3cm9uZyB0ZW5hbnQgZm9yXG4gKiBSTFMuIFNlcnZpY2VzIHdpdGggYSBkaWZmZXJlbnQgcmVxdWVzdCBib3VuZGFyeSBzdXBwbHkgdGhlaXIgb3duIHJlc29sdmVyIChlLmcuIHBsYXRmb3JtXG4gKiBzZXRzIHRoZSBzY29wZSBwcmUtYXV0aCBmcm9tIGFuIHVudmVyaWZpZWQgSldUIHBlZWsgc28gdW5hdXRoZW50aWNhdGVkIGVuZHBvaW50cyBzdGlsbFxuICogZ2V0IGEgc2FuZSBkZWZhdWx0KS5cbiAqL1xuZXhwb3J0IHR5cGUgVGVuYW50U2NvcGVSZXNvbHZlciA9IChyZXE6IFJlcXVlc3QpID0+IFRlbmFudENvbnRleHQ7XG5cbi8qKiBEZWZhdWx0IHJlc29sdmVyOiB0aGUgYXV0aGVudGljYXRlZCBpZGVudGl0eSdzIG9yZyArIHN1cGVyLWFkbWluIGZsYWcsIHBsdXNcbiAqICB0aGUgYWN0aXZlLW9yZyBwYXJlbnQgKG9yZyDihpIgdGVhbSBoaWVyYXJjaHkpIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzIGNhblxuICogIHJlYWNoIGl0IHdpdGhvdXQgYSByZXF1ZXN0LiAqL1xuY29uc3QgaWRlbnRpdHlTY29wZTogVGVuYW50U2NvcGVSZXNvbHZlciA9IChyZXEpID0+ICh7XG4gIG9yZ0lkOiBnZXRDb250ZXh0KHJlcSkuaWRlbnRpdHkub3JnSWQsXG4gIGlzU3VwZXJBZG1pbjogaXNTeXN0ZW1BZG1pbihyZXEpLFxuICBwYXJlbnRPcmdJZDogcmVxLnVzZXI/LnBhcmVudE9yZ2FuaXphdGlvbklkLFxufSk7XG5cbi8qKlxuICogRXN0YWJsaXNoIHRoZSByZXF1ZXN0J3Mgcm93LWxldmVsLXNlY3VyaXR5IHRlbmFudCBzY29wZS5cbiAqXG4gKiBSdW5zIHRoZSByZXN0IG9mIHRoZSByZXF1ZXN0IGluc2lkZSBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluIH0pYCAoYW5cbiAqIEFzeW5jTG9jYWxTdG9yYWdlIHNjb3BlKSBzbyBldmVyeSBgd2l0aFRlbmFudFR4YCBxdWVyeSBkb3duc3RyZWFtIGNhbiBgU0VUIExPQ0FMYCB0aGVcbiAqIFBvc3RncmVzIEdVQ3MgdGhhdCBSTFMgcG9saWNpZXMgcmVhZC4gV2l0aG91dCB0aGlzLCByZWFkcyBhZ2FpbnN0IEZPUkNFLVJMUyB0YWJsZXMgKGUuZy5cbiAqIGBwbHVnaW5zYCwgYHBpcGVsaW5lc2ApIHJ1biB3aXRoIGVtcHR5IEdVQ3MgYW5kIHNpbGVudGx5IHJldHVybiBubyByb3dzIOKAlCB0aGUgXCJzZXQgb25jZVxuICogYXQgdGhlIHJlcXVlc3QgYm91bmRhcnlcIiBib29rZW5kIHRoZSBSTFMgZW5mb3JjZW1lbnQgcGxhbiBjYWxscyBmb3IuXG4gKlxuICogRGVmYXVsdCBwbGFjZW1lbnQgaXMgQUZURVIgYHJlcXVpcmVBdXRoYCArIGByZXF1aXJlT3JnSWRgICh0aGUgcm91dGUgZmFjdG9yaWVzIGRvIHRoaXMpO1xuICogcGFzcyBhIGN1c3RvbSBgcmVzb2x2ZWAgZm9yIGEgZGlmZmVyZW50IGJvdW5kYXJ5LiBBIHRocm93biByZXNvbHZlciBtZWFucyB0ZW5hbnQgaWRlbnRpdHlcbiAqIGNvdWxkIE5PVCBiZSBlc3RhYmxpc2hlZCAoYSB3aXJpbmcgYnVnIOKAlCB0aGlzIHJ1bnMgYWZ0ZXIgYXV0aCkg4oCUIHdlIGhhcmQtRkFJTCB0aGUgcmVxdWVzdFxuICogKDUwMCB2aWEgbmV4dChlcnIpKSByYXRoZXIgdGhhbiBwcm9jZWVkLiBQcm9jZWVkaW5nIHdvdWxkIHJ1biBxdWVyaWVzIHdpdGggZW1wdHkgUkxTIEdVQ3M7XG4gKiB1bmRlciBGT1JDRSBSTFMgdGhhdCBoaWRlcyByb3dzLCBidXQgd2hpbGUgUkxTIGlzIGluIG93bmVyLWJ5cGFzcyBtb2RlIHRoZSBhcHAtbGF5ZXIgV0hFUkVcbiAqIGNsYXVzZSBpcyB0aGUgb25seSB0ZW5hbnQgZ2F0ZSwgc28gYSBzY29wZWxlc3MgcmVxdWVzdCBtdXN0IG5vdCBzaWxlbnRseSBjb250aW51ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhUZW5hbnRDb250ZXh0KHJlc29sdmU6IFRlbmFudFNjb3BlUmVzb2x2ZXIgPSBpZGVudGl0eVNjb3BlKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCBfcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgbGV0IHNjb3BlOiBUZW5hbnRDb250ZXh0O1xuICAgIHRyeSB7XG4gICAgICBzY29wZSA9IHJlc29sdmUocmVxKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcnVuV2l0aFRlbmFudENvbnRleHQoc2NvcGUsICgpID0+IG5leHQoKSk7XG4gIH07XG59XG4iXX0=
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuYW50LWNvbnRleHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3RlbmFudC1jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzNELE9BQU8sRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxpQ0FBaUMsQ0FBQztBQUUzRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFZOUM7O2tDQUVrQztBQUNsQyxNQUFNLGFBQWEsR0FBd0IsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbkQsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSx1RUFBdUU7SUFDdkUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSztJQUNyQyxZQUFZLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQztJQUNoQyxXQUFXLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxvQkFBb0I7Q0FDNUMsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLE9BQU8sR0FBd0IsYUFBYTtJQUM1RSxPQUFPLENBQUMsR0FBWSxFQUFFLElBQWMsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDaEUsSUFBSSxLQUFvQixDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUNELG9CQUFvQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgaXNTeXN0ZW1BZG1pbiB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IHJ1bldpdGhUZW5hbnRDb250ZXh0LCB0eXBlIFRlbmFudENvbnRleHQgfSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1kYXRhJztcbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UsIE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gJy4vZ2V0LWNvbnRleHQuanMnO1xuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBSTFMgdGVuYW50IHNjb3BlIGZvciBhIHJlcXVlc3QuIFRoZSBkZWZhdWx0IHJlYWRzIHRoZSBDQUxMRVInc1xuICogYXV0aGVudGljYXRlZCBpZGVudGl0eSBvcmcgKGBjdHguaWRlbnRpdHkub3JnSWRgLCB2YWxpZGF0ZWQgYnkgcmVxdWlyZU9yZ0lkKSDigJQgTk9UXG4gKiBgZ2V0T3JnSWQocmVxKWAsIHdoaWNoIHByZWZlcnMgcm91dGUgcGFyYW1zICh0aGUgcXVlcmllZCBzY29wZSksIHRoZSB3cm9uZyB0ZW5hbnQgZm9yXG4gKiBSTFMuIFNlcnZpY2VzIHdpdGggYSBkaWZmZXJlbnQgcmVxdWVzdCBib3VuZGFyeSBzdXBwbHkgdGhlaXIgb3duIHJlc29sdmVyIChlLmcuIHBsYXRmb3JtXG4gKiBzZXRzIHRoZSBzY29wZSBwcmUtYXV0aCBmcm9tIGFuIHVudmVyaWZpZWQgSldUIHBlZWsgc28gdW5hdXRoZW50aWNhdGVkIGVuZHBvaW50cyBzdGlsbFxuICogZ2V0IGEgc2FuZSBkZWZhdWx0KS5cbiAqL1xuZXhwb3J0IHR5cGUgVGVuYW50U2NvcGVSZXNvbHZlciA9IChyZXE6IFJlcXVlc3QpID0+IFRlbmFudENvbnRleHQ7XG5cbi8qKiBEZWZhdWx0IHJlc29sdmVyOiB0aGUgYXV0aGVudGljYXRlZCBpZGVudGl0eSdzIG9yZyArIHN1cGVyLWFkbWluIGZsYWcsIHBsdXNcbiAqICB0aGUgYWN0aXZlLW9yZyBwYXJlbnQgKG9yZyDihpIgdGVhbSBoaWVyYXJjaHkpIHNvIGRvd25zdHJlYW0gc2lkZS1lZmZlY3RzIGNhblxuICogIHJlYWNoIGl0IHdpdGhvdXQgYSByZXF1ZXN0LiAqL1xuY29uc3QgaWRlbnRpdHlTY29wZTogVGVuYW50U2NvcGVSZXNvbHZlciA9IChyZXEpID0+ICh7XG4gIC8vIGBpZGVudGl0eS5vcmdJZGAgaXMgYWxyZWFkeSBub3JtYWxpemVkICh0cmltbWVkICsgbG93ZXJjYXNlZCkgb25jZSBhdFxuICAvLyByZXNvbHV0aW9uIGluIGFwaS1jb3JlJ3MgYGdldElkZW50aXR5YCwgc28gdGhlIEdVQyBzZXQgaGVyZSBtYXRjaGVzIHRoZVxuICAvLyBhcHAtbGF5ZXIgV0hFUkUgY2xhdXNlcyBleGFjdGx5IOKAlCBubyBhZC1ob2MgcmUtbm9ybWFsaXphdGlvbiBuZWVkZWQuXG4gIG9yZ0lkOiBnZXRDb250ZXh0KHJlcSkuaWRlbnRpdHkub3JnSWQsXG4gIGlzU3VwZXJBZG1pbjogaXNTeXN0ZW1BZG1pbihyZXEpLFxuICBwYXJlbnRPcmdJZDogcmVxLnVzZXI/LnBhcmVudE9yZ2FuaXphdGlvbklkLFxufSk7XG5cbi8qKlxuICogRXN0YWJsaXNoIHRoZSByZXF1ZXN0J3Mgcm93LWxldmVsLXNlY3VyaXR5IHRlbmFudCBzY29wZS5cbiAqXG4gKiBSdW5zIHRoZSByZXN0IG9mIHRoZSByZXF1ZXN0IGluc2lkZSBgcnVuV2l0aFRlbmFudENvbnRleHQoeyBvcmdJZCwgaXNTdXBlckFkbWluIH0pYCAoYW5cbiAqIEFzeW5jTG9jYWxTdG9yYWdlIHNjb3BlKSBzbyBldmVyeSBgd2l0aFRlbmFudFR4YCBxdWVyeSBkb3duc3RyZWFtIGNhbiBgU0VUIExPQ0FMYCB0aGVcbiAqIFBvc3RncmVzIEdVQ3MgdGhhdCBSTFMgcG9saWNpZXMgcmVhZC4gV2l0aG91dCB0aGlzLCByZWFkcyBhZ2FpbnN0IEZPUkNFLVJMUyB0YWJsZXMgKGUuZy5cbiAqIGBwbHVnaW5zYCwgYHBpcGVsaW5lc2ApIHJ1biB3aXRoIGVtcHR5IEdVQ3MgYW5kIHNpbGVudGx5IHJldHVybiBubyByb3dzIOKAlCB0aGUgXCJzZXQgb25jZVxuICogYXQgdGhlIHJlcXVlc3QgYm91bmRhcnlcIiBib29rZW5kIHRoZSBSTFMgZW5mb3JjZW1lbnQgcGxhbiBjYWxscyBmb3IuXG4gKlxuICogRGVmYXVsdCBwbGFjZW1lbnQgaXMgQUZURVIgYHJlcXVpcmVBdXRoYCArIGByZXF1aXJlT3JnSWRgICh0aGUgcm91dGUgZmFjdG9yaWVzIGRvIHRoaXMpO1xuICogcGFzcyBhIGN1c3RvbSBgcmVzb2x2ZWAgZm9yIGEgZGlmZmVyZW50IGJvdW5kYXJ5LiBBIHRocm93biByZXNvbHZlciBtZWFucyB0ZW5hbnQgaWRlbnRpdHlcbiAqIGNvdWxkIE5PVCBiZSBlc3RhYmxpc2hlZCAoYSB3aXJpbmcgYnVnIOKAlCB0aGlzIHJ1bnMgYWZ0ZXIgYXV0aCkg4oCUIHdlIGhhcmQtRkFJTCB0aGUgcmVxdWVzdFxuICogKDUwMCB2aWEgbmV4dChlcnIpKSByYXRoZXIgdGhhbiBwcm9jZWVkLiBQcm9jZWVkaW5nIHdvdWxkIHJ1biBxdWVyaWVzIHdpdGggZW1wdHkgUkxTIEdVQ3M7XG4gKiB1bmRlciBGT1JDRSBSTFMgdGhhdCBoaWRlcyByb3dzLCBidXQgd2hpbGUgUkxTIGlzIGluIG93bmVyLWJ5cGFzcyBtb2RlIHRoZSBhcHAtbGF5ZXIgV0hFUkVcbiAqIGNsYXVzZSBpcyB0aGUgb25seSB0ZW5hbnQgZ2F0ZSwgc28gYSBzY29wZWxlc3MgcmVxdWVzdCBtdXN0IG5vdCBzaWxlbnRseSBjb250aW51ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhUZW5hbnRDb250ZXh0KHJlc29sdmU6IFRlbmFudFNjb3BlUmVzb2x2ZXIgPSBpZGVudGl0eVNjb3BlKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCBfcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgbGV0IHNjb3BlOiBUZW5hbnRDb250ZXh0O1xuICAgIHRyeSB7XG4gICAgICBzY29wZSA9IHJlc29sdmUocmVxKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcnVuV2l0aFRlbmFudENvbnRleHQoc2NvcGUsICgpID0+IG5leHQoKSk7XG4gIH07XG59XG4iXX0=
@@ -1 +1,2 @@
1
1
  export * from './sse-connection-manager.js';
2
+ export * from './sse-ticket-store.js';
package/lib/http/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  export * from './sse-connection-manager.js';
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLGNBQWMsNkJBQTZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuZXhwb3J0ICogZnJvbSAnLi9zc2UtY29ubmVjdGlvbi1tYW5hZ2VyLmpzJztcbiJdfQ==
4
+ export * from './sse-ticket-store.js';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsY0FBYyx1QkFBdUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5leHBvcnQgKiBmcm9tICcuL3NzZS1jb25uZWN0aW9uLW1hbmFnZXIuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zc2UtdGlja2V0LXN0b3JlLmpzJztcbiJdfQ==
@@ -1,4 +1,5 @@
1
1
  import type { Response } from 'express';
2
+ import { type SSETicketStore } from './sse-ticket-store.js';
2
3
  /**
3
4
  * Event types for SSE logging
4
5
  */
@@ -68,6 +69,19 @@ export interface SSEManagerOptions {
68
69
  maxTicketsPerOrg?: number;
69
70
  /** Ticket TTL in ms (default: `SSE_TICKET_TTL_MS` from api-core). */
70
71
  ticketTtlMs?: number;
72
+ /**
73
+ * Ticket + stream-ownership backend. Defaults to an in-memory store (correct
74
+ * single-replica only). Inject `createEnvRedisTicketStore()` (or a bespoke
75
+ * `SSETicketStore`) so ticket mint/redeem AND stream ownership work across
76
+ * horizontally-scaled pods and — critically — so the platform stream producer
77
+ * (a different service) can bind ownership that this service reads.
78
+ */
79
+ ticketStore?: SSETicketStore;
80
+ /**
81
+ * TTL for a stream-ownership binding (default: `SSE_STREAM_OWNER_TTL_MS` env or
82
+ * 1h). Long enough to outlive a build; the producer re-binds as needed.
83
+ */
84
+ streamOwnerTtlMs?: number;
71
85
  }
72
86
  /**
73
87
  * A build-log stream subject id: either a dashed UUID (api-server's `uuid()`)
@@ -84,7 +98,7 @@ export type CreateTicketResult = {
84
98
  ticket: string;
85
99
  } | {
86
100
  ok: false;
87
- reason: 'org-limit' | 'capacity';
101
+ reason: 'org-limit' | 'capacity' | 'forbidden';
88
102
  };
89
103
  /**
90
104
  * SSE Manager statistics
@@ -118,16 +132,17 @@ export declare class SSEManager {
118
132
  * map mirrors `clients[].orgId` counts at all times. Orgs reach zero are
119
133
  * deleted to keep the map bounded. */
120
134
  private orgClientCounts;
121
- /** Single-use SSE tickets, keyed by opaque ticket id. Bounded by
122
- * `maxTotalTickets` / `maxTicketsPerOrg`; swept on the cleanup interval and
123
- * validated (expiry) at consume time. */
124
- private tickets;
135
+ /** Ticket + stream-ownership backend (in-memory default; Redis for multi-pod).
136
+ * Bounded by `maxTotalTickets` / `maxTicketsPerOrg`, enforced in createTicket;
137
+ * expiry is validated at consume time and swept on the cleanup interval. */
138
+ private readonly ticketStore;
125
139
  private readonly maxClientsPerRequest;
126
140
  private readonly maxTotalClients;
127
141
  private readonly maxClientsPerOrg;
128
142
  private readonly maxTotalTickets;
129
143
  private readonly maxTicketsPerOrg;
130
144
  private readonly ticketTtlMs;
145
+ private readonly streamOwnerTtlMs;
131
146
  private readonly clientTimeoutMs;
132
147
  private cleanupInterval;
133
148
  constructor(options?: SSEManagerOptions);
@@ -142,8 +157,28 @@ export declare class SSEManager {
142
157
  * expected to have already format-validated against {@link SSE_REQUEST_ID_RE}.
143
158
  */
144
159
  private static normalizeRequestId;
145
- /** Count of live (unexpired) tickets currently held for an org. */
146
- private countLiveTicketsForOrg;
160
+ /**
161
+ * Canonical form of an orgId for ownership equality checks: trimmed and
162
+ * lowercased. The stream PRODUCER (bindStreamOwner) and the ticket-minting
163
+ * CONSUMER (createTicket) run in different services, so a casing / whitespace
164
+ * drift between how each renders the same org would otherwise make the owner
165
+ * comparison in {@link createTicket} false-`forbidden` the real owner.
166
+ * Normalizing both sides — mirroring {@link normalizeRequestId} — closes that.
167
+ */
168
+ private static normalizeOrgId;
169
+ /**
170
+ * Record the org that OWNS a stream subject. The stream PRODUCER calls this
171
+ * when it creates a build-log stream so that ticket minting can assert the
172
+ * caller's org owns the subject (see {@link createTicket}). Backed by the
173
+ * injected ticket store, so when a Redis store is wired the platform producer
174
+ * (a different service sharing the same Redis) can bind ownership that this
175
+ * service reads — closing the cross-tenant attach gap where any org could mint
176
+ * a ticket for a guessed requestId.
177
+ *
178
+ * @param requestId - The stream subject (format-validated by the caller).
179
+ * @param orgId - The owning org (normalized internally via normalizeOrgId).
180
+ */
181
+ bindStreamOwner(requestId: string, orgId: string): Promise<void>;
147
182
  /**
148
183
  * Mint a short-lived, single-use SSE ticket bound to `orgId` AND a specific
149
184
  * stream subject (`requestId`). Clients POST to obtain one (JWT-authenticated)
@@ -152,16 +187,23 @@ export declare class SSEManager {
152
187
  * ticket can then only be consumed to open that one subject's stream — see
153
188
  * {@link consumeTicket} — which is what enforces per-subject authorization.
154
189
  *
190
+ * ORG-OWNERSHIP: if a stream owner has been bound for this subject (via
191
+ * {@link bindStreamOwner}) and it is a DIFFERENT org, minting is refused
192
+ * (`reason: 'forbidden'`) — an org cannot mint a ticket for another org's
193
+ * stream even if it guesses the requestId. When no owner is bound (producer
194
+ * wiring not yet present), minting falls back to binding the ticket to the
195
+ * caller's own org, preserving current behavior.
196
+ *
155
197
  * Bounded by `maxTotalTickets` (process-wide) and `maxTicketsPerOrg`
156
198
  * (per-tenant). Mirrors the message-service notifications ticket store.
157
199
  *
158
- * @param orgId - Owning org (already normalized by the caller).
200
+ * @param orgId - Owning org (normalized internally via normalizeOrgId).
159
201
  * @param requestId - The build-log stream subject this ticket authorizes.
160
202
  * The caller must have format-validated it (see {@link SSE_REQUEST_ID_RE}).
161
203
  * @returns `{ ok: true, ticket }` on success, or `{ ok: false, reason }`
162
- * where reason is `'org-limit'` (per-org cap) or `'capacity'` (total cap).
204
+ * where reason is `'org-limit'`, `'capacity'`, or `'forbidden'`.
163
205
  */
164
- createTicket(orgId: string, requestId: string): CreateTicketResult;
206
+ createTicket(orgId: string, requestId: string): Promise<CreateTicketResult>;
165
207
  /**
166
208
  * Validate and CONSUME a ticket for a specific stream subject. Single-use:
167
209
  * the ticket is deleted whether or not it turns out to be valid, so a replay
@@ -180,9 +222,9 @@ export declare class SSEManager {
180
222
  * @param requestId - The stream subject from the URL path (`:requestId`),
181
223
  * already format-validated by the caller.
182
224
  */
183
- consumeTicket(ticketId: string, requestId: string): {
225
+ consumeTicket(ticketId: string, requestId: string): Promise<{
184
226
  orgId: string;
185
- } | null;
227
+ } | null>;
186
228
  /**
187
229
  * Adds a client to the SSE manager
188
230
  *
@@ -260,7 +302,7 @@ export declare class SSEManager {
260
302
  query?: {
261
303
  ticket?: unknown;
262
304
  };
263
- }, res: Response) => void;
305
+ }, res: Response) => Promise<void>;
264
306
  /**
265
307
  * Start periodic cleanup of stale connections
266
308
  */