import fetch from "node-fetch";
import * as cheerio from "cheerio";
import { Guideline, GuidelinesMap } from "./types";
import fs from "fs";
import path from "path";
require("dotenv").config({ path: path.resolve(__dirname, "../../.env") });
console.error("π§ Environment loaded - Base URL:", process.env.CONFLUENCE_BASE_URL);
const BASE_URL = process.env.CONFLUENCE_BASE_URL;
const EMAIL = process.env.CONFLUENCE_EMAIL!;
const API_TOKEN = process.env.CONFLUENCE_API_TOKEN!;
const MAIN_PAGE_ID = process.env.CONFLUENCE_MAIN_PAGE_ID!;
// if (!MAIN_PAGE_ID) throw new Error("Environment variable MAIN_PAGE_ID is not set.");
// Helper: returns the authorization header
function getAuthHeader() {
const creds = Buffer.from(`${EMAIL}:${API_TOKEN}`).toString("base64");
return { Authorization: `Basic ${creds}` };
}
// Fetch a Confluence page by ID
async function fetchPageContent(pageId: string): Promise<string> {
const url = `${BASE_URL}/rest/api/content/${pageId}?expand=body.view`;
const res = await fetch(url, { headers: getAuthHeader() });
if (!res.ok) {
const errorText = await res.text();
throw new Error(`Failed to fetch page ${pageId}: ${res.status} ${res.statusText} - ${errorText}`);
}
const data = (await res.json()) as { body: { view: { value: string } } };
return data.body.view.value; // HTML string
}
// Object to store all guidelines
export const guidelines: GuidelinesMap = {};
// Helper: fetch child page IDs for a given page
async function fetchChildPageIds(pageId: string): Promise<string[]> {
const url = `${BASE_URL}/rest/api/content/${pageId}/child/page`;
const res = await fetch(url, { headers: getAuthHeader() });
if (!res.ok) {
const errorText = await res.text();
throw new Error(`Failed to fetch child pages for ${pageId}: ${res.status} ${res.statusText} - ${errorText}`);
}
const data: any = await res.json();
if (!data.results) return [];
return data.results.map((page: any) => page.id);
}
// Load comprehensive TBC guidelines from documentation
function loadComprehensiveTBCGuidelines(): GuidelinesMap {
const comprehensive: GuidelinesMap = {};
// 1. Backend Development Guidelines
comprehensive["backend-comprehensive"] = {
title: "Backend Development - Comprehensive Rules",
text: `
PROGRAMMING LANGUAGE: C#/.NET with LTS versions only
FRAMEWORK: ASP.NET Core Web API exclusively
ARCHITECTURE: Clean Architecture (Domain β Application β Infrastructure β Presentation)
PROJECT STRUCTURE:
β
Use .NET project templates
β
Implement Clean Architecture layers
β
Follow Domain-Driven Design principles
AUTHENTICATION & AUTHORIZATION:
β
Use JWT tokens for API authentication
β
Implement role-based authorization
β
Use Azure AD/Identity Server integration
DATABASE ACCESS:
β
SQL Server as primary database
β
Entity Framework Core for data access
β
Use Repository + Unit of Work patterns
β
Implement database migrations
β
Use AsNoTracking() for read-only queries
TESTING:
β
Unit testing with xUnit framework
β
80%+ code coverage requirement
β
Integration testing for APIs
β
SonarQube integration for quality gates
SECURITY:
β
Follow OWASP security guidelines
β
Implement input validation
β
Use parameterized queries
β
Sanitize all user inputs
β
Regular NuGet vulnerability checks
`,
url: "internal://backend-comprehensive"
};
// 2. API Design - Complete Rules
comprehensive["api-design-complete"] = {
title: "API Design - Complete Rules",
text: `
URI NAMING CONVENTIONS:
β
Use lowercase letters only
β
Use hyphens (-) instead of underscores (_)
β
Use plural nouns for collections
β
Use hierarchical structure: /api/v1/users/{id}/orders
HTTP METHODS:
β
GET: Retrieve data (idempotent)
β
POST: Create new resources
β
PUT: Update entire resource (idempotent)
β
PATCH: Partial updates
β
DELETE: Remove resources (idempotent)
PAYLOAD MODELING:
β
Use consistent JSON formats
β
camelCase for property names
β
Include proper validation
β
Use DTOs, never return entities directly
ERROR HANDLING:
β
Use appropriate HTTP status codes
β
Provide meaningful error messages
β
Include error codes for programmatic handling
β
Consistent error format across APIs
API VERSIONING:
β
Use versioned endpoints: /api/v1/, /api/v2/
β
Maintain backward compatibility
β
Proper deprecation strategies
HTTP STATUS CODES:
β
200: OK (successful GET, PUT, PATCH)
β
201: Created (successful POST)
β
204: No Content (successful DELETE)
β
400: Bad Request (validation errors)
β
401: Unauthorized (authentication required)
β
403: Forbidden (insufficient permissions)
β
404: Not Found (resource doesn't exist)
β
500: Internal Server Error (server issues)
`,
url: "internal://api-design-complete"
};
// 3. Logging - Comprehensive Rules
comprehensive["logging-comprehensive"] = {
title: "Logging - Comprehensive Standards",
text: `
LOGGING FRAMEWORK: Serilog preferred, NLog acceptable
DEPENDENCY INJECTION: Use ILogger<T> interface always
STRUCTURED LOGGING:
β
Use structured logging with parameters
β
Example: _logger.LogInformation("Processing {UserId} for {ActionType}", userId, actionType)
β Avoid: _logger.LogInformation("Processing " + userId + " for " + actionType)
LOG LEVELS:
β
Trace: Detailed diagnostic information
β
Debug: Development-time diagnostic information
β
Information: General application flow
β
Warning: Unexpected situations that don't stop execution
β
Error: Error events that allow application to continue
β
Critical: Fatal errors that may cause application termination
SENSITIVE DATA:
β
Use TBC.Common.Serilog for automatic masking
β
Never log passwords, tokens, or PII directly
β
Implement log sanitization for sensitive fields
CONSOLE OUTPUT:
β Never use Console.WriteLine() in production code
β
Always use ILogger<T> interface for all logging needs
PERFORMANCE:
β
Use conditional logging for expensive operations
β
Implement proper log levels to control verbosity
`,
url: "internal://logging-comprehensive"
};
// 4. Entity Framework - Complete Guidelines
comprehensive["ef-comprehensive"] = {
title: "Entity Framework - Complete Guidelines",
text: `
ORM: Entity Framework Core exclusively
DATABASE: SQL Server 2019+ as primary database
PERFORMANCE OPTIMIZATION:
β
Use AsNoTracking() for read-only queries
β
Use Select() projections to fetch specific fields
β
Implement proper indexing strategies
β
Use async methods: ToListAsync(), SaveChangesAsync()
REPOSITORY PATTERN:
β
Use Repository + Unit of Work patterns
β
Use TBC.Common.Repository libraries
β Avoid direct DbContext usage in controllers
β
Implement generic repository interfaces
MIGRATIONS:
β
Use code-first migrations
β
Proper migration naming conventions
β
Test migrations on staging before production
QUERY OPTIMIZATION:
β
Use Include() for eager loading when needed
β
Avoid N+1 query problems
β
Use Split Queries for complex includes
β
Implement query result caching where appropriate
DATA VALIDATION:
β
Use Data Annotations for basic validation
β
Implement Fluent Validation for complex rules
β
Server-side validation always required
`,
url: "internal://ef-comprehensive"
};
// 5. Security - Complete Guidelines
comprehensive["security-comprehensive"] = {
title: "Security - Complete Guidelines",
text: `
OWASP COMPLIANCE:
β
Follow OWASP Top 10 security risks
β
Implement proper input validation
β
Use parameterized queries (prevent SQL injection)
β
Implement proper authentication and authorization
INPUT VALIDATION:
β
Validate all user inputs server-side
β
Use whitelist approach for validation
β
Sanitize inputs before processing
β
Implement proper error messages without revealing system details
AUTHENTICATION:
β
Use JWT tokens for API authentication
β
Implement proper token expiration
β
Use secure token storage mechanisms
β
Implement refresh token patterns
AUTHORIZATION:
β
Use role-based access control (RBAC)
β
Implement claim-based authorization
β
Apply principle of least privilege
β
Validate permissions at multiple layers
DATA PROTECTION:
β
Use HTTPS for all communications
β
Encrypt sensitive data at rest
β
Implement proper key management
β
Use secure configuration management
`,
url: "internal://security-comprehensive"
};
// 6. Testing - Complete Standards
comprehensive["testing-comprehensive"] = {
title: "Testing - Complete TBC Standards",
text: `
TESTING FRAMEWORK: xUnit for .NET exclusively
CODE COVERAGE: Minimum 80% coverage required
TESTING STRATEGY: Unit β Integration β E2E testing pyramid
UNIT TESTING:
β
Test all business logic methods
β
Use AAA pattern (Arrange, Act, Assert)
β
Mock external dependencies (IRepository, ILogger, etc.)
β
Test both positive and negative scenarios
β
Use meaningful test names: Should_ReturnError_When_UserNotFound()
INTEGRATION TESTING:
β
Test API endpoints with TestServer
β
Test database operations with test database
β
Test external service integrations
β
Use WebApplicationFactory for API testing
MOCKING:
β
Use Moq library for mocking
β
Mock ILogger<T>, IRepository, external services
β
Verify method calls and parameters
β
Setup return values for different scenarios
SONARQUBE INTEGRATION:
β
Quality gates must pass before merge
β
No code smells, bugs, or vulnerabilities
β
Maintain code coverage thresholds
`,
url: "internal://testing-comprehensive"
};
// 7. Project Structure & Architecture
comprehensive["architecture-comprehensive"] = {
title: "Clean Architecture & Project Structure",
text: `
ARCHITECTURE PATTERN: Clean Architecture mandatory
LAYERS: Domain β Application β Infrastructure β Presentation
PROJECT STRUCTURE:
β
Domain Layer: Entities, Value Objects, Domain Services
β
Application Layer: Use Cases, DTOs, Interfaces
β
Infrastructure Layer: Data Access, External Services
β
Presentation Layer: Controllers, ViewModels
DEPENDENCY INJECTION:
β
Use .NET Core built-in IoC container
β
Register services with appropriate lifetimes
β
Use interfaces for all dependencies
β
Constructor injection preferred
DOMAIN-DRIVEN DESIGN:
β
Rich domain models with behavior
β
Aggregate roots for consistency boundaries
β
Domain events for cross-cutting concerns
β
Value objects for primitive obsession
CQRS PATTERN:
β
Separate read and write models
β
Use MediatR for command/query handling
β
Implement command and query handlers
β
Read models optimized for queries
`,
url: "internal://architecture-comprehensive"
};
// 8. Background Tasks & Jobs
comprehensive["background-tasks"] = {
title: "Background Tasks & Job Processing",
text: `
BACKGROUND SERVICE: Use TBC.Common.BackgroundTasks
JOB SCHEDULING: Hangfire or Quartz.NET integration
ASYNC PROCESSING: For long-running operations
IMPLEMENTATION:
β
Use IHostedService for background services
β
Implement proper cancellation token handling
β
Use TBC.Common.BackgroundTasks library
β
Queue jobs for async processing
ERROR HANDLING:
β
Implement retry mechanisms
β
Dead letter queue for failed jobs
β
Proper logging of job execution
β
Monitor job performance and health
PATTERNS:
β
Fire-and-forget for non-critical tasks
β
Delayed jobs for scheduled operations
β
Recurring jobs for maintenance tasks
β
Batch jobs for bulk operations
`,
url: "internal://background-tasks"
};
// 9. File Storage & Management
comprehensive["file-storage"] = {
title: "File Storage & Management Guidelines",
text: `
CLOUD STORAGE: Azure Blob Storage preferred
FILE VALIDATION: Mandatory for all uploads
VIRUS SCANNING: Required for uploaded files
FILE UPLOAD:
β
Validate file types and sizes
β
Generate unique file names
β
Use secure file storage paths
β
Implement virus scanning
SECURITY:
β
Validate file extensions against whitelist
β
Check file content, not just extension
β
Limit file sizes per upload
β
Scan for malware before storage
PERFORMANCE:
β
Use streaming for large files
β
Implement progress tracking
β
Compress files when appropriate
β
Use CDN for file distribution
`,
url: "internal://file-storage"
};
// 10. Messaging & Integration
comprehensive["messaging-comprehensive"] = {
title: "Messaging & Integration Patterns",
text: `
MESSAGE BROKERS: RabbitMQ or TIBCO EMS
INTEGRATION PATTERNS: Event-driven architecture
ASYNC MESSAGING: For microservice communication
IMPLEMENTATION:
β
Use message queues for decoupling
β
Implement event sourcing patterns
β
Use publish-subscribe for events
β
Implement saga patterns for distributed transactions
MESSAGE DESIGN:
β
Include correlation IDs
β
Use versioned message schemas
β
Include timestamp and source information
β
Implement idempotent message handlers
ERROR HANDLING:
β
Dead letter queues for failed messages
β
Retry mechanisms with exponential backoff
β
Circuit breaker patterns
β
Message deduplication
`,
url: "internal://messaging-comprehensive"
};
// 11. API Documentation & Contracts
comprehensive["api-documentation"] = {
title: "API Documentation & Contract Standards",
text: `
DOCUMENTATION: OpenAPI/Swagger mandatory
CONTRACT-FIRST: Define API contracts before implementation
VERSIONING: Document all API versions
SWAGGER/OPENAPI:
β
Complete API documentation required
β
Include request/response examples
β
Document all HTTP status codes
β
Include authentication requirements
API CONTRACTS:
β
Define clear request/response DTOs
β
Include validation rules in documentation
β
Specify required vs optional fields
β
Document error response formats
EXAMPLES:
β
Provide realistic request examples
β
Include common error scenarios
β
Document authentication flows
β
Include rate limiting information
`,
url: "internal://api-documentation"
};
// 12. Performance & Optimization
comprehensive["performance-optimization"] = {
title: "Performance & Optimization Guidelines",
text: `
DATABASE OPTIMIZATION: Query performance critical
CACHING: Redis for distributed caching
ASYNC PATTERNS: Use async/await throughout
DATABASE PERFORMANCE:
β
Use AsNoTracking() for read-only queries
β
Implement proper indexing strategies
β
Use Select() projections to limit data
β
Batch operations when possible
CACHING STRATEGIES:
β
Cache frequently accessed data
β
Use Redis for distributed caching
β
Implement cache-aside pattern
β
Set appropriate expiration times
API PERFORMANCE:
β
Implement pagination for large datasets
β
Use compression for responses
β
Implement rate limiting
β
Monitor response times and optimize
`,
url: "internal://performance-optimization"
};
// 13. Monitoring & Observability
comprehensive["monitoring-observability"] = {
title: "Monitoring & Observability Standards",
text: `
TELEMETRY: Application Insights integration
HEALTH CHECKS: Mandatory for all services
METRICS: Custom metrics for business operations
MONITORING:
β
Implement health check endpoints
β
Use Application Insights for telemetry
β
Monitor application performance
β
Set up alerts for critical issues
LOGGING INTEGRATION:
β
Structured logging with Serilog
β
Log correlation IDs for tracing
β
Use Graylog for centralized logging
β
Include performance metrics in logs
METRICS:
β
Track business-relevant metrics
β
Monitor API response times
β
Track error rates and patterns
β
Implement custom counters and gauges
`,
url: "internal://monitoring-observability"
};
// 14. Deployment & DevOps
comprehensive["deployment-devops"] = {
title: "Deployment & DevOps Standards",
text: `
CI/CD: Azure DevOps pipelines mandatory
DEPLOYMENT: Blue-green deployment strategy
CONFIGURATION: Environment-specific configs
BUILD PIPELINE:
β
Automated builds on code commit
β
Run all tests in pipeline
β
SonarQube quality gates
β
Security vulnerability scanning
DEPLOYMENT STRATEGY:
β
Blue-green deployments for zero downtime
β
Database migration automation
β
Rollback procedures documented
β
Environment-specific configurations
INFRASTRUCTURE:
β
Infrastructure as Code (Terraform/ARM)
β
Container deployment with Docker
β
Kubernetes orchestration where applicable
β
Load balancer configuration
`,
url: "internal://deployment-devops"
};
return comprehensive;
}
// Load only guideline pages linked from the main page
export async function loadGuidelines(): Promise<GuidelinesMap> {
console.error(`π Loading guidelines from page ID: ${MAIN_PAGE_ID}`);
const html = await fetchPageContent(MAIN_PAGE_ID!);
const $ = cheerio.load(html);
const urls: string[] = [];
$("a").each((_, el) => {
const href = $(el).attr("href");
if (href && href.includes("/pages/")) urls.push(href);
});
console.error(`π Found ${urls.length} guideline page links`);
for (const url of urls) {
const match = url.match(/\/pages\/(\d+)/);
if (!match) continue;
const pageId = match[1];
try {
const contentHtml = await fetchPageContent(pageId);
const $$ = cheerio.load(contentHtml);
const title = $$("h1").first().text() || url;
let text = $$.text().replace(/\s+/g, " ").trim();
// Find and fetch content of any linked guideline pages within this page
const subUrls: string[] = [];
$$('a').each((_, el) => {
const href = $$(el).attr('href');
if (href && href.includes('/pages/')) subUrls.push(href);
});
// Fetch all sub guideline pages in parallel
const subPagePromises = subUrls.map(async (subUrl) => {
const subMatch = subUrl.match(/\/pages\/(\d+)/);
if (!subMatch) return '';
const subPageId = subMatch[1];
try {
const subContentHtml = await fetchPageContent(subPageId);
const $$$ = cheerio.load(subContentHtml);
const subTitle = $$$('h1').first().text() || subUrl;
const subText = $$$.text().replace(/\s+/g, ' ').trim();
return `\n\n---\nIncluded from: ${subTitle}\n${subText}\nURL: ${subUrl}`;
} catch (err) {
console.error(`β Failed to load included page ${subUrl}:`, err);
return '';
}
});
const subPageContents = await Promise.all(subPagePromises);
text += subPageContents.join('');
guidelines[pageId] = { title, text: `${text}\nURL: ${url}`, url };
console.error(`β
Loaded guideline: ${title}`);
} catch (err) {
console.error(`β Failed to load ${url}:`, err);
}
}
// Add comprehensive TBC guidelines from documentation
// Load comprehensive TBC rules from local documentation
const comprehensiveGuidelines = loadComprehensiveTBCGuidelines();
Object.assign(guidelines, comprehensiveGuidelines);
// Add critical API naming guideline
guidelines["api-naming-critical"] = {
title: "CRITICAL: API Endpoint Naming Standard",
text: `MANDATORY TBC BANK STANDARD: API endpoints MUST use kebab-case (hyphens), NOT underscores.
β
CORRECT EXAMPLES:
- /api/v1/user-profiles
- /api/v1/account-transactions
- /api/v1/payment-methods
- /api/v1/loan-applications
β WRONG EXAMPLES:
- /api/v1/user_profiles (underscores not allowed)
- /api/v1/account_transactions (underscores not allowed)
- /api/v1/payment_methods (underscores not allowed)
This is a mandatory organizational standard that must be followed in ALL API endpoints.`,
url: "internal://api-naming-standard"
};
console.error(`π Total guidelines loaded: ${Object.keys(guidelines).length}`);
return guidelines;
}