C4 Diagrams
Level 1: System Context
C4Context
title System Context Diagram - Blue Braces (Recron)
Person(user, "Job Seeker", "Prepares for interviews, tracks job applications, builds CV")
Person(moderator, "Moderator", "Approves/rejects proposed questions")
System(recron, "Blue Braces Platform", "Interview preparation, job search management, and CV portfolio building")
System_Ext(keycloak, "Keycloak", "Identity & Access Management")
System_Ext(openai, "OpenAI API", "AI-powered answers, offer parsing, CV matching, portfolio import")
Rel(user, recron, "Uses", "HTTPS")
Rel(moderator, recron, "Moderates", "HTTPS")
Rel(recron, keycloak, "Authentication", "OIDC")
Rel(recron, openai, "AI features", "HTTPS")
Level 2: Container Diagram
C4Container
title Container Diagram - Blue Braces
Person(user, "User")
System_Boundary(recron, "Blue Braces Platform") {
Container(webapp, "Web Application", "SolidJS, TypeScript, CSS Modules", "SPA for interview prep, job tracking, and CV building")
Container(gateway, "API Gateway", "YARP", "Routes requests to microservices")
Container(questions_api, "Questions API", ".NET 11", "Interview questions, categories, voting, learning, quiz")
Container(organizer_api, "Organizer API", ".NET 11", "Job offers, interviews, AI parsing, stats, CV matching")
Container(portfolio_api, "Portfolio API", ".NET 11", "CV portfolios, variants, AI import from LinkedIn/PDF")
Container(users_api, "Users API", ".NET 11", "User profiles, token details")
ContainerDb(questions_db, "Questions DB", "PostgreSQL", "Categories, questions, votes, learning")
ContainerDb(organizer_db, "Organizer DB", "PostgreSQL", "Offers, interviews, dictionaries")
ContainerDb(portfolio_db, "Portfolio DB", "PostgreSQL", "CV portfolios (JSONB)")
ContainerDb(users_db, "Users DB", "PostgreSQL", "User profiles")
}
System_Ext(keycloak, "Keycloak")
System_Ext(openai, "OpenAI")
Rel(user, webapp, "Uses", "HTTPS")
Rel(webapp, gateway, "API calls", "HTTPS")
Rel(gateway, questions_api, "/questions/*", "HTTP")
Rel(gateway, organizer_api, "/organizer/*", "HTTP")
Rel(gateway, portfolio_api, "/portfolio/*", "HTTP")
Rel(gateway, users_api, "/users/*", "HTTP")
Rel(questions_api, questions_db, "Reads/Writes")
Rel(organizer_api, organizer_db, "Reads/Writes")
Rel(portfolio_api, portfolio_db, "Reads/Writes")
Rel(users_api, users_db, "Reads/Writes")
Rel(questions_api, keycloak, "Validates JWT")
Rel(organizer_api, keycloak, "Validates JWT")
Rel(portfolio_api, keycloak, "Validates JWT")
Rel(users_api, keycloak, "Validates JWT")
Rel(questions_api, openai, "AI answers")
Rel(organizer_api, openai, "AI parsing, CV matching")
Rel(portfolio_api, openai, "AI import")
Level 3: Component Diagram (Questions API)
C4Component
title Component Diagram - Questions API (14 endpoints)
Container_Boundary(api, "Questions API") {
Component(endpoints, "Feature Endpoints", "Minimal API", "14 endpoints for questions, categories, quiz")
Component(handlers, "CQRS Handlers", "Command/Query Handlers", "Business logic execution")
Component(dbcontext, "ApplicationDbContext", "EF Core 10", "Data access layer")
Component(ai_client, "IChatClient", "Microsoft.Extensions.AI", "AI answer generation")
Component(user_service, "ICurrentUserService", "Domain Service", "Current user context")
}
ContainerDb(postgres, "PostgreSQL")
System_Ext(keycloak, "Keycloak")
System_Ext(openai, "OpenAI")
Rel(endpoints, handlers, "Dispatches to")
Rel(handlers, dbcontext, "Queries/Commands")
Rel(handlers, ai_client, "Generate answers")
Rel(handlers, user_service, "Get user context")
Rel(dbcontext, postgres, "SQL")
Rel(ai_client, openai, "Chat completions")
Rel(user_service, keycloak, "Extract from JWT")
Level 3: Component Diagram (Organizer API)
C4Component
title Component Diagram - Organizer API (17 endpoints)
Container_Boundary(api, "Organizer API") {
Component(endpoints, "Feature Endpoints", "Minimal API", "17 endpoints for offers, interviews, AI, stats")
Component(handlers, "CQRS Handlers", "Command/Query Handlers", "Business logic")
Component(validators, "Validators", "FluentValidation", "Request validation")
Component(dbcontext, "ApplicationDbContext", "EF Core 10", "Data access")
Component(ai_client, "IChatClient", "Microsoft.Extensions.AI", "Offer parsing, CV matching")
}
ContainerDb(postgres, "PostgreSQL")
System_Ext(keycloak, "Keycloak")
System_Ext(openai, "OpenAI")
Rel(endpoints, validators, "Validates input")
Rel(endpoints, handlers, "Dispatches to")
Rel(handlers, dbcontext, "Queries/Commands")
Rel(handlers, ai_client, "AI features")
Rel(dbcontext, postgres, "SQL")
Rel(endpoints, keycloak, "JWT validation")
Rel(ai_client, openai, "Chat completions")
Level 3: Component Diagram (Portfolio API)
C4Component
title Component Diagram - Portfolio API (6 endpoints)
Container_Boundary(api, "Portfolio API") {
Component(endpoints, "Feature Endpoints", "Minimal API", "6 endpoints for CRUD + AI import")
Component(handlers, "CQRS Handlers", "Command/Query Handlers", "Business logic")
Component(validators, "Validators", "FluentValidation", "Request validation")
Component(dbcontext, "ApplicationDbContext", "EF Core 10", "Data access (JSONB)")
Component(ai_client, "IChatClient", "Microsoft.Extensions.AI", "LinkedIn/PDF parsing")
}
ContainerDb(postgres, "PostgreSQL")
System_Ext(keycloak, "Keycloak")
System_Ext(openai, "OpenAI")
Rel(endpoints, validators, "Validates input")
Rel(endpoints, handlers, "Dispatches to")
Rel(handlers, dbcontext, "Queries/Commands")
Rel(handlers, ai_client, "AI import")
Rel(dbcontext, postgres, "SQL + JSONB")
Rel(endpoints, keycloak, "JWT validation")
Rel(ai_client, openai, "Chat completions")
Level 3: Component Diagram (Users API)
C4Component
title Component Diagram - Users API (3 endpoints)
Container_Boundary(api, "Users API") {
Component(endpoints, "Feature Endpoints", "Minimal API", "3 endpoints for token details + profile")
Component(handlers, "CQRS Handlers", "Command/Query Handlers", "Business logic")
Component(dbcontext, "ApplicationDbContext", "EF Core 10", "Data access")
Component(user_service, "ICurrentUserService", "Domain Service", "Current user context")
}
ContainerDb(postgres, "PostgreSQL")
System_Ext(keycloak, "Keycloak")
Rel(endpoints, handlers, "Dispatches to")
Rel(handlers, dbcontext, "Queries/Commands")
Rel(handlers, user_service, "Get user context")
Rel(dbcontext, postgres, "SQL")
Rel(user_service, keycloak, "Extract from JWT")
Data Flow: Question Proposal Workflow
sequenceDiagram
participant U as User
participant W as Webapp
participant G as Gateway
participant Q as Questions API
participant DB as PostgreSQL
U->>W: Click "Propose Question"
W->>W: Open FormDialog
U->>W: Submit question text
W->>G: POST /questions/questions/propose
G->>Q: Forward request
Q->>Q: Validate JWT & extract user
Q->>DB: Insert QuestionEntity (status: Pending)
DB-->>Q: Success
Q-->>G: 201 Created
G-->>W: Success
W->>W: Invalidate questions query
W->>U: Show success message
Note over U,DB: Moderator Approval Flow
participant M as Moderator
M->>W: View pending questions
W->>G: GET /questions (filter: pending)
G->>Q: Forward
Q->>DB: Query pending questions
DB-->>Q: Results
Q-->>W: Pending questions list
M->>W: Click "Approve"
W->>G: POST /questions/approve
G->>Q: Forward
Q->>DB: Update status to Approved
Q-->>W: Success
Data Flow: AI Answer Generation
sequenceDiagram
participant U as User
participant W as Webapp
participant G as Gateway
participant Q as Questions API
participant AI as OpenAI
participant DB as PostgreSQL
U->>W: Click "Ask AI" on question
W->>G: GET /questions/ask-ai?questionId=xxx
G->>Q: Forward request
Q->>DB: Get question details
DB-->>Q: Question with category context
Q->>AI: ChatCompletion request
Note right of AI: System prompt + question
AI-->>Q: Generated answer
Q->>DB: Update question description
DB-->>Q: Success
Q-->>G: AskAiResponse
G-->>W: Answer text
W->>W: Invalidate & refetch
W->>U: Display AI answer
Data Flow: AI Offer Parsing
sequenceDiagram
participant U as User
participant W as Webapp
participant G as Gateway
participant O as Organizer API
participant AI as OpenAI
U->>W: Paste URL or offer text
W->>G: POST /organizer/offers/parse-ai
G->>O: Forward request
O->>AI: Parse offer content
Note right of AI: Extract structured fields
AI-->>O: JSON with name, company, salary, etc.
O-->>G: ParseOfferResponse
G-->>W: Parsed offer data
W->>W: Pre-fill offer form
U->>W: Review & submit
W->>G: POST /organizer/offers
G->>O: Create offer
O-->>W: Created offer
Data Flow: CV-to-Offer Matching
sequenceDiagram
participant U as User
participant W as Webapp
participant G as Gateway
participant O as Organizer API
participant AI as OpenAI
U->>W: Open offer drawer, select CV variant
W->>G: POST /organizer/offers/match-cv
G->>O: Forward (offer + portfolio data)
O->>AI: Compare CV against offer requirements
Note right of AI: Score, strengths, gaps
AI-->>O: MatchCvResult JSON
O-->>G: MatchCvResponse
G-->>W: Score + analysis
W->>U: Display score ring, strengths, gaps, recommendations