// tools/create-spec-hu/quality-helpers.ts — Private helper generators extracted from create-spec-hu
// SPEC-010: Quality Guidelines, Testing Strategy, Impact Analysis sections.
// SPEC-027: multi-tenancy criteria.
// SPEC-010: Quality Guidelines section
export function generateQualityGuidelines(spec, knowledge) {
    const lines = ['', '## Quality Guidelines', ''];
    // Suggest design patterns based on type
    const patterns = suggestPatterns(spec);
    if (patterns.length > 0) {
        lines.push('**Recommended Design Patterns:**', '');
        for (const p of patterns) {
            lines.push(`- **${p.name}**: ${p.reason}`);
        }
        lines.push('');
    }
    // SOLID principles relevant to this type
    if (spec.type === 'refactor' || spec.scope === 'cross-module' || spec.scope === 'architectural') {
        lines.push('**SOLID Checklist:**', '');
        lines.push('- [ ] SRP: Each class/module has a single reason to change');
        lines.push('- [ ] OCP: Extend behavior without modifying existing code');
        lines.push('- [ ] DIP: Depend on abstractions, not concrete implementations');
        lines.push('');
    }
    // Architecture-specific guidelines
    if (knowledge?.architecture.primary === 'clean-architecture' ||
        knowledge?.architecture.primary === 'hexagonal') {
        lines.push('**Architecture Compliance:**', '');
        lines.push('- [ ] Domain logic does not import infrastructure dependencies');
        lines.push('- [ ] New ports defined as interfaces, adapters implement them');
        lines.push('');
    }
    // Security guidelines for backend/fullstack features
    if (spec.target === 'backend' || spec.target === 'fullstack') {
        lines.push('**Security Requirements:**', '');
        lines.push('- [ ] All inputs validated and sanitized');
        lines.push('- [ ] No hardcoded secrets or credentials');
        lines.push('- [ ] Parameterized queries (no string concatenation in SQL)');
        lines.push('');
    }
    // SPEC-013: Mobile platform guidelines
    if (spec.target === 'ios') {
        lines.push('**iOS Guidelines:**', '');
        lines.push('- [ ] No hardcoded API keys (use Keychain or xcconfig)');
        lines.push('- [ ] ATS (App Transport Security) enforced');
        lines.push('- [ ] Memory management: avoid retain cycles with [weak self]');
        lines.push('');
    }
    if (spec.target === 'android') {
        lines.push('**Android Guidelines:**', '');
        lines.push('- [ ] No hardcoded secrets (use BuildConfig or EncryptedSharedPreferences)');
        lines.push('- [ ] Network security config enforced (cleartext disabled)');
        lines.push('- [ ] ProGuard/R8 rules defined for release builds');
        lines.push('');
    }
    return lines;
}
export function suggestPatterns(spec) {
    const suggestions = [];
    if (spec.type === 'feature' && (spec.target === 'backend' || spec.target === 'fullstack')) {
        suggestions.push({
            name: 'Repository Pattern',
            reason: 'Abstracts data access from business logic',
        });
    }
    if (spec.type === 'refactor') {
        suggestions.push({
            name: 'Strategy Pattern',
            reason: 'Replace conditional logic with polymorphism',
        });
        suggestions.push({ name: 'Facade Pattern', reason: 'Simplify complex subsystem interfaces' });
    }
    if (spec.scope === 'cross-module') {
        suggestions.push({
            name: 'Mediator / Event Bus',
            reason: 'Decouple cross-module communication',
        });
    }
    if (spec.type === 'infra') {
        suggestions.push({
            name: 'Adapter Pattern',
            reason: 'Isolate infrastructure from domain logic',
        });
    }
    return suggestions;
}
// SPEC-010: Testing Strategy section
export function generateTestingStrategy(spec) {
    const lines = ['', '## Testing Strategy', ''];
    lines.push('**Unit Tests:**', '');
    if (spec.type === 'bugfix') {
        lines.push('- [ ] Regression test for the reported bug');
        lines.push('- [ ] Edge cases around the bug fix');
    }
    else {
        lines.push('- [ ] Core business logic covered by unit tests');
        lines.push('- [ ] Happy path + failure modes tested');
    }
    lines.push('');
    if (spec.scope !== 'trivial') {
        lines.push('**Integration Tests:**', '');
        lines.push('- [ ] End-to-end flow through affected layers');
        if (spec.target === 'backend' || spec.target === 'fullstack') {
            lines.push('- [ ] API contract tests (request/response validation)');
        }
        // SPEC-013: mobile UI testing
        if (spec.target === 'ios') {
            lines.push('- [ ] XCUITest UI tests for main user flows');
            lines.push('- [ ] Snapshot tests for visual regressions');
        }
        if (spec.target === 'android') {
            lines.push('- [ ] Espresso/Compose UI tests for main user flows');
            lines.push('- [ ] Screenshot tests for visual regressions');
        }
        lines.push('');
    }
    if (spec.scope === 'architectural' || spec.scope === 'cross-module') {
        lines.push('**Contract / Compatibility Tests:**', '');
        lines.push('- [ ] Existing consumers of changed interfaces still work');
        lines.push('- [ ] No breaking changes in public API surface');
        lines.push('');
    }
    return lines;
}
// SPEC-010: Impact Analysis section
export function generateImpactAnalysis(spec) {
    const lines = ['', '## Impact Analysis', ''];
    const impact = spec.impactAnalysis;
    lines.push('**Affected Modules:**', '');
    if (impact && impact.affectedModules.length > 0) {
        for (const mod of impact.affectedModules) {
            lines.push(`- ${mod}`);
        }
    }
    else {
        lines.push('- (List modules affected by this change)');
    }
    lines.push('');
    lines.push('**Breaking Changes:**', '');
    lines.push(impact?.breakingChanges
        ? '- WARNING: YES — document breaking changes and migration guide below'
        : '- No breaking changes expected');
    lines.push('');
    lines.push('**Rollback Plan:**', '');
    if (impact?.rollbackPlan) {
        lines.push(`- ${impact.rollbackPlan}`);
    }
    else {
        lines.push('- [ ] Define rollback procedure (feature flag, revert commit, migration down)');
    }
    lines.push('');
    if (impact?.requiresMigration) {
        lines.push('**Migration Required:** YES', '');
        lines.push(impact.migrationReversible
            ? '- Migration is reversible (up + down scripts)'
            : '- Warning: Migration is NOT reversible — extra caution required');
        lines.push('');
    }
    return lines;
}
/**
 * SPEC-027: Generate multi-tenancy isolation criteria when project uses multi-tenant patterns.
 * Checks for known tenant ID fields or the 'multi-tenant' convention flag.
 */
export function generateMultiTenancyCriteria(knowledge) {
    // Use nullish coalescing to handle partially-typed test mocks safely
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    const conventions = knowledge.conventions ?? {};
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    const stack = knowledge.stack ?? [];
    const isMultiTenant = conventions['multi-tenant'] === 'true' ||
        conventions.multiTenant === 'true' ||
        stack.some((s) => /tenant/i.test(s));
    if (!isMultiTenant) {
        return [];
    }
    return [
        '',
        '## Multi-Tenancy Isolation',
        '',
        '> This project uses multi-tenant architecture. Every feature must enforce tenant isolation.',
        '',
        '- [ ] All data queries are filtered by `tenant_id` / `organization_id`',
        '- [ ] This endpoint cannot access data from other tenants (verified by test)',
        '- [ ] Logs and audit trail include the `tenant_id` for every operation',
        '- [ ] New DB migrations include RLS policies or tenant filter conditions',
    ];
}
//# sourceMappingURL=quality-helpers.js.map