All files / vqa/_collections/utils finding-id.util.ts

100% Statements 43/43
100% Branches 12/12
100% Functions 2/2
100% Lines 43/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 441x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 1x 1x 5x 1x 1x 3x 3x 3x 3x 3x 5x 5x 5x 1x 1x 1x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * `DyE2E_VQA_FindingId_Util` — stable finding-ID generálás (`VQA-<projekt>-<feature>-NNN`).
 *
 * Az AI agent ezt használja a finding-write-or, hogy a következő szabad
 * sorszámot kapjon a feature-en belül. Az existingFindingIds set-jét a bundle
 * vagy a projekt BACKLOG.md adja.
 */
export class DyE2E_VQA_FindingId_Util {
 
  /** Következő szabad sorszám (001-tól, padding 3). */
  static nextId(
    projectSlug: string,
    featureSlug: string,
    existingFindingIds: string[],
  ): string {
    if (!/^[a-z0-9-]+$/.test(projectSlug)) {
      throw new Error(`projectSlug must be lowercase kebab-case: '${projectSlug}'`);
    }
    if (!/^[a-z0-9-]+$/.test(featureSlug)) {
      throw new Error(`featureSlug must be lowercase kebab-case: '${featureSlug}'`);
    }
    const prefix: string = `VQA-${projectSlug}-${featureSlug}-`;
    const usedNums: number[] = existingFindingIds
      .filter((id) => id.startsWith(prefix))
      .map((id) => parseInt(id.slice(prefix.length), 10))
      .filter((n) => !isNaN(n));
    const next: number = (usedNums.length === 0 ? 0 : Math.max(...usedNums)) + 1;
    return `${prefix}${String(next).padStart(3, '0')}`;
  }
 
  /** Parse-back: kibontja a komponenseket egy ID-ből. Null ha nem-konform. */
  static parse(findingId: string): { projectSlug: string; featureSlug: string; seq: number } | null {
    const match: RegExpMatchArray | null = findingId.match(/^VQA-([a-z0-9-]+?)-([a-z0-9-]+?)-(\d{3,})$/);
    if (!match) {
      return null;
    }
    return {
      projectSlug: match[1],
      featureSlug: match[2],
      seq: parseInt(match[3], 10),
    };
  }
}