- Zmiana nazwy: "Norda Biznes Hub" → "Norda Biznes Partner" - Aktualizacja modelu AI: Gemini 2.0 Flash → Gemini 3 Flash - Zachowano historyczne odniesienia w timeline i dokumentacji Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
54 KiB
Flask Application Component Diagram (C4 Level 3)
Document Version: 1.0 Last Updated: 2026-01-10 Status: Production LIVE Diagram Type: C4 Model - Level 3 (Components)
Overview
This diagram shows the internal component structure of the Flask web application. It illustrates:
- What components exist within the Flask application (routes, services, models)
- How components interact with each other
- Responsibilities of each component layer
- Code organization and module structure
Abstraction Level: Component (C4 Level 3) Audience: Developers, Technical Leads Purpose: Understanding internal application architecture for development and maintenance
Application Size: ~13,144 lines of Python code Total Routes: 90+ HTTP endpoints Database Models: 36 SQLAlchemy models Service Components: 7 service layer modules
Flask Component Architecture Diagram
graph TB
%% External input
HTTP["📨 HTTP Requests<br/>(from NPM Proxy)"]
%% Flask App boundary
subgraph "Flask Application (app.py - 13,144 lines)"
%% Request handling layer
subgraph "Request Handling Layer"
Router["🔀 Flask Router<br/>(URL routing)"]
Auth["🔐 Authentication<br/>(Flask-Login)<br/>User loader, session mgmt"]
CSRF["🛡️ CSRF Protection<br/>(Flask-WTF)<br/>Token validation"]
RateLimit["⏱️ Rate Limiter<br/>(Flask-Limiter)<br/>200/day, 50/hour"]
end
%% Route categories
subgraph "Route Controllers (90+ endpoints)"
PublicRoutes["🌐 Public Routes (8)<br/>/, /search, /company/slug<br/>/aktualnosci, /health"]
AuthRoutes["🔑 Auth Routes (7)<br/>/register, /login, /logout<br/>/verify-email, /reset-password"]
UserRoutes["👤 User Routes (21)<br/>/dashboard, /chat, /forum<br/>/wiadomosci, /kalendarz, /tablica"]
AdminRoutes["👨💼 Admin Routes (28)<br/>/admin/seo, /admin/forum<br/>/admin/users, /admin/fees"]
APIRoutes["🔌 API Routes (26)<br/>/api/chat, /api/seo, /api/companies<br/>/api/notifications, /api/recommendations"]
AuditRoutes["📊 Audit Routes (4)<br/>/audit/seo, /audit/social<br/>/audit/gbp, /audit/it"]
end
%% Service layer
subgraph "Service Layer (7 modules)"
SearchService["🔍 SearchService<br/>search_service.py<br/>~400 lines<br/><br/>• Company search<br/>• NIP/REGON lookup<br/>• PostgreSQL FTS<br/>• Synonym expansion<br/>• Fuzzy matching<br/>• Result scoring"]
ChatService["💬 ChatService<br/>nordabiz_chat.py<br/>~800 lines<br/><br/>• AI conversation<br/>• Context building<br/>• Session management<br/>• Token tracking<br/>• Message history"]
GeminiService["🤖 GeminiService<br/>gemini_service.py<br/>~500 lines<br/><br/>• AI text generation<br/>• Image analysis<br/>• Streaming responses<br/>• Cost tracking<br/>• Error handling"]
EmailService["📧 EmailService<br/>email_service.py<br/>~200 lines<br/><br/>• MS Graph OAuth<br/>• Email sending<br/>• Template rendering<br/>• Error handling"]
KRSService["🏛️ KRSService<br/>krs_api_service.py<br/>~300 lines<br/><br/>• Company verification<br/>• Registry data fetch<br/>• Data validation<br/>• Caching"]
GBPService["📊 GBPService<br/>gbp_audit_service.py<br/>~600 lines<br/><br/>• Places API search<br/>• Profile analysis<br/>• AI recommendations<br/>• Audit reporting"]
ITService["🖥️ ITService<br/>it_audit_service.py<br/>~500 lines<br/><br/>• IT maturity assess<br/>• Question scoring<br/>• Report generation<br/>• Recommendations"]
end
%% Database layer
subgraph "Database Layer (database.py - ~1,500 lines)"
ORM["🗄️ SQLAlchemy ORM<br/>Session management<br/>Query building"]
subgraph "Domain Models (36 total)"
CoreModels["📂 Core Domain (5)<br/>Company, User, Category<br/>CompanyOwner, SearchHistory"]
ContentModels["📝 Content Domain (6)<br/>CompanyNews, NewsVerification<br/>ForumTopic, ForumReply, ClassifiedAd<br/>CompanyPhoto"]
SocialModels["👥 Social Domain (5)<br/>CompanySocialMedia<br/>SocialMediaAudit<br/>SocialMediaProfile<br/>Recommendation, Like"]
AuditModels["📊 Audit Domain (4)<br/>SEOMetrics, GBPAudit<br/>ITInfrastructureAudit<br/>DigitalMaturityScore"]
ChatModels["💬 Chat Domain (3)<br/>ChatSession, ChatMessage<br/>GeminiUsage"]
CommunityModels["🤝 Community Domain (5)<br/>Event, EventAttendee<br/>MembershipFee, Message<br/>Notification"]
SystemModels["⚙️ System Domain (8)<br/>EmailVerification, PasswordReset<br/>APIQuota, APILog, DataQualityCheck<br/>ActivityLog, AuditLog, SystemSetting"]
end
end
%% Template rendering
Templates["📄 Template Engine<br/>(Jinja2)<br/>HTML rendering<br/>Template inheritance"]
%% Static files
Static["🎨 Static Assets<br/>CSS, JavaScript, Images"]
end
%% External dependencies
Database[("💾 PostgreSQL<br/>Database<br/>36 tables")]
GeminiAPI["🤖 Gemini API<br/>(external)"]
BraveAPI["🔍 Brave API<br/>(external)"]
PageSpeedAPI["📊 PageSpeed API<br/>(external)"]
PlacesAPI["📍 Places API<br/>(external)"]
KRSAPI["🏛️ KRS API<br/>(external)"]
MSGraphAPI["📧 MS Graph API<br/>(external)"]
%% Request flow
HTTP --> Router
Router --> Auth
Router --> CSRF
Router --> RateLimit
Auth --> PublicRoutes
Auth --> AuthRoutes
Auth --> UserRoutes
Auth --> AdminRoutes
Auth --> APIRoutes
Auth --> AuditRoutes
%% Route to service connections
PublicRoutes --> SearchService
PublicRoutes --> Templates
UserRoutes --> ChatService
UserRoutes --> SearchService
UserRoutes --> Templates
AdminRoutes --> GBPService
AdminRoutes --> ITService
AdminRoutes --> Templates
APIRoutes --> ChatService
APIRoutes --> SearchService
APIRoutes --> GBPService
AuditRoutes --> Templates
%% Service to service connections
ChatService --> SearchService
ChatService --> GeminiService
GBPService --> GeminiService
%% Service to external API connections
GeminiService --> GeminiAPI
ChatService --> GeminiAPI
SearchService --> Database
EmailService --> MSGraphAPI
KRSService --> KRSAPI
GBPService --> PlacesAPI
%% Database access
PublicRoutes --> ORM
UserRoutes --> ORM
AdminRoutes --> ORM
APIRoutes --> ORM
ORM --> CoreModels
ORM --> ContentModels
ORM --> SocialModels
ORM --> AuditModels
ORM --> ChatModels
ORM --> CommunityModels
ORM --> SystemModels
CoreModels --> Database
ContentModels --> Database
SocialModels --> Database
AuditModels --> Database
ChatModels --> Database
CommunityModels --> Database
SystemModels --> Database
%% Template rendering
Templates --> Static
%% Styling
classDef routeStyle fill:#1168bd,stroke:#0b4884,color:#ffffff,stroke-width:2px
classDef serviceStyle fill:#85bbf0,stroke:#5d92c7,color:#000000,stroke-width:2px
classDef modelStyle fill:#50c878,stroke:#3da35f,color:#000000,stroke-width:2px
classDef infraStyle fill:#ff9f1c,stroke:#cc7f16,color:#000000,stroke-width:2px
classDef externalStyle fill:#999999,stroke:#666666,color:#ffffff,stroke-width:2px
classDef databaseStyle fill:#438dd5,stroke:#2e6295,color:#ffffff,stroke-width:3px
class PublicRoutes,AuthRoutes,UserRoutes,AdminRoutes,APIRoutes,AuditRoutes routeStyle
class SearchService,ChatService,GeminiService,EmailService,KRSService,GBPService,ITService serviceStyle
class CoreModels,ContentModels,SocialModels,AuditModels,ChatModels,CommunityModels,SystemModels modelStyle
class Router,Auth,CSRF,RateLimit,ORM,Templates,Static infraStyle
class GeminiAPI,BraveAPI,PageSpeedAPI,PlacesAPI,KRSAPI,MSGraphAPI externalStyle
class Database databaseStyle
Component Descriptions
1. Request Handling Layer
🔀 Flask Router
Location: app.py (Flask core)
Responsibility: URL pattern matching and request routing
Technology: Flask routing decorators (@app.route())
Key Features:
- 90+ registered routes across 6 categories
- RESTful API endpoints (
/api/*) - Dynamic URL parameters (
<slug>,<id>) - Multiple HTTP methods (GET, POST, PUT, DELETE)
Example Routes:
@app.route('/') # Homepage
@app.route('/company/<slug>') # Company profile
@app.route('/api/chat/<id>/message') # API endpoint
@app.route('/admin/seo') # Admin panel
🔐 Authentication (Flask-Login)
Location: app.py (lines ~200-400)
Responsibility: User authentication and session management
Technology: Flask-Login extension
Key Features:
- Session-based authentication (cookies)
- User loader callback (
@login_manager.user_loader) - Login required decorator (
@login_required) - Remember me functionality
- Session persistence
Authentication Levels:
- Public: Anonymous access allowed
- User: Requires login (
current_user.is_authenticated) - Admin: Requires admin flag (
current_user.is_admin)
Session Storage: Server-side sessions in PostgreSQL (or cookies for simple data)
🛡️ CSRF Protection (Flask-WTF)
Location: app.py (Flask-WTF integration)
Responsibility: Cross-Site Request Forgery protection
Technology: Flask-WTF CSRFProtect
Key Features:
- Automatic CSRF token generation
- Form validation with CSRF tokens
- AJAX request protection (X-CSRFToken header)
- Token rotation on authentication changes
Protected Routes: All POST, PUT, DELETE requests
Exempt Routes: /health, /api/webhooks (if needed)
⏱️ Rate Limiter (Flask-Limiter)
Location: app.py (Flask-Limiter integration)
Responsibility: API rate limiting and abuse prevention
Technology: Flask-Limiter
Rate Limits:
- Global Default: 200 requests/day, 50 requests/hour
- Chat API: 100 requests/day (AI cost control)
- Search API: 200 requests/hour
- Admin API: Unlimited (trusted users)
Storage: Redis (production) or in-memory (development)
Key Function: get_remote_address() for IP-based limiting
2. Route Controllers (90+ endpoints)
🌐 Public Routes (8 endpoints)
Authentication: None required Purpose: Publicly accessible pages
| Route | Method | Description | Template |
|---|---|---|---|
/ |
GET | Homepage - company directory | index.html |
/search |
GET | Search companies | search_results.html |
/company/<slug> |
GET | Company profile page | company_detail.html |
/aktualnosci |
GET | News feed | news.html |
/health |
GET | Health check (JSON) | - |
/release-notes |
GET | Release notes | release_notes.html |
/api/companies |
GET | JSON export of companies | - |
/api/verify-nip |
GET | NIP verification API | - |
Key Features:
- No authentication required
- Cacheable responses
- SEO-optimized (meta tags, structured data)
- Rate limited to prevent scraping
🔑 Auth Routes (7 endpoints)
Authentication: Mixed (public registration, authenticated logout) Purpose: User authentication lifecycle
| Route | Method | Description | Authentication |
|---|---|---|---|
/register |
GET, POST | User registration | Public |
/login |
GET, POST | User login | Public |
/logout |
GET | User logout | Required |
/verify-email/<token> |
GET | Email verification | Public |
/resend-verification |
POST | Resend verification email | Public |
/reset-password |
GET, POST | Password reset request | Public |
/reset-password/<token> |
GET, POST | Password reset form | Public |
Security Features:
- Password hashing (bcrypt)
- Email verification required
- Password strength validation
- Rate limiting on registration (5/hour)
- CSRF protection on all forms
👤 User Routes (21 endpoints)
Authentication: Required (@login_required)
Purpose: Authenticated user features
Categories:
- Dashboard:
/dashboard- User overview - Chat:
/chat- AI assistant interface - Forum:
/forum,/forum/nowy,/forum/<id>,/forum/<id>/odpowiedz(7 routes) - Messages:
/wiadomosci,/wiadomosci/nowa,/wiadomosci/<id>(5 routes) - Calendar:
/kalendarz,/kalendarz/<id>,/kalendarz/<id>/rsvp(3 routes) - Classifieds:
/tablica,/tablica/nowe,/tablica/<id>(3 routes) - IT Audit:
/it-audit/form- IT maturity self-assessment
Key Features:
- Personal dashboard with activity feed
- AI chat with conversation history
- Forum participation (topics, replies, moderation)
- Private messaging between members
- Event calendar with RSVP
- Classifieds board for member offers
- IT infrastructure self-audit
👨💼 Admin Routes (28 endpoints)
Authentication: Required + Admin flag (current_user.is_admin)
Purpose: Administrative functions
Categories:
SEO Management (1 route):
/admin/seo- SEO audit dashboard
Social Media Management (2 routes):
/admin/social-media- Social media profiles overview/admin/social-audit- Social media audit results
GBP Management (1 route):
/admin/gbp-audit- Google Business Profile audit dashboard
IT Audit Management (1 route):
/admin/it-audit- IT audit results dashboard
Forum Moderation (5 routes):
/admin/forum- Forum overview/admin/forum/topic/<id>/pin- Pin topic/admin/forum/topic/<id>/delete- Delete topic/admin/forum/reply/<id>/delete- Delete reply/admin/forum/user/<id>/ban- Ban user from forum
Recommendations Management (3 routes):
/admin/recommendations- Pending recommendations/admin/recommendations/<id>/approve- Approve recommendation/admin/recommendations/<id>/reject- Reject recommendation
User Management (8 routes):
/admin/users- User list/admin/users/<id>/toggle-admin- Toggle admin status/admin/users/<id>/toggle-active- Activate/deactivate user/admin/users/<id>/reset-password- Admin password reset/admin/users/<id>/delete- Delete user account/admin/users/<id>/impersonate- Login as user (debug)/admin/users/export- Export user data (CSV)/admin/users/bulk-action- Bulk operations
Fees Management (5 routes):
/admin/fees- Membership fees overview/admin/fees/generate- Generate monthly fees/admin/fees/<id>/mark-paid- Mark fee as paid/admin/fees/<id>/send-reminder- Send payment reminder/admin/fees/export- Export fees data
Events Management (3 routes):
/admin/kalendarz- Event management/admin/kalendarz/nowy- Create new event/admin/kalendarz/<id>/edit- Edit event
Analytics (3 routes):
/admin/chat-analytics- AI chat usage analytics/admin/debug- Debug information panel/admin/digital-maturity- Digital maturity overview
Security:
- All routes check
current_user.is_admin - Action logging to
audit_logtable - Confirmation dialogs for destructive actions
- CSRF protection on all POST requests
🔌 API Routes (26 endpoints)
Authentication: Mixed (some require login, some admin-only) Purpose: JSON API for AJAX requests and external integrations Response Format: JSON
Chat API (4 endpoints):
POST /api/chat/start- Start new chat session (user auth)POST /api/chat/<id>/message- Send chat message (user auth)GET /api/chat/<id>/history- Get chat history (user auth)DELETE /api/chat/<id>- Delete chat session (user auth)
SEO API (3 endpoints):
POST /api/seo/audit- Trigger SEO audit (admin only)GET /api/seo/audit/<slug>- Get audit results (public)GET /api/seo/dashboard- Dashboard data (admin only)
GBP API (3 endpoints):
POST /api/gbp/audit- Trigger GBP audit (admin only)GET /api/gbp/audit/<slug>- Get audit results (public)GET /api/gbp/dashboard- Dashboard data (admin only)
Social Media API (1 endpoint):
POST /api/social/audit- Trigger social audit (admin only)
Notifications API (4 endpoints):
GET /api/notifications- Get user notifications (user auth)PUT /api/notifications/<id>/read- Mark as read (user auth)PUT /api/notifications/read-all- Mark all as read (user auth)DELETE /api/notifications/<id>- Delete notification (user auth)
Recommendations API (3 endpoints):
GET /api/recommendations/<id>- Get recommendation details (user auth)POST /api/recommendations/create- Create recommendation (user auth)DELETE /api/recommendations/<id>- Delete recommendation (user auth)
Messages API (1 endpoint):
GET /api/messages/unread-count- Get unread count (user auth)
Utility API (5 endpoints):
GET /api/verify-nip- Verify NIP number (public)GET /api/check-email- Check email availability (public)GET /api/model-info- Get AI model info (public)GET /api/companies- Export companies JSON (public)GET /api/search-suggestions- Search autocomplete (public)
Common Patterns:
- JSON request/response
- HTTP status codes (200, 201, 400, 401, 403, 404, 500)
- Error messages in
{"error": "message"}format - Success messages in
{"success": true, "data": {...}}format - Rate limiting applied
- CORS headers when needed
📊 Audit Routes (4 endpoints)
Authentication: Public (read-only audit reports) Purpose: Display audit results for companies
| Route | Description | Template |
|---|---|---|
/audit/seo/<slug> |
SEO audit report | audit_seo.html |
/audit/social/<slug> |
Social media audit report | audit_social.html |
/audit/gbp/<slug> |
Google Business Profile audit | audit_gbp.html |
/audit/it/<slug> |
IT infrastructure audit | audit_it.html |
Key Features:
- Public access (no login required)
- Read-only reports
- PDF export capability (planned)
- Share links for business owners
- Recommendations and action items
- Historical audit comparisons
3. Service Layer (7 modules)
🔍 SearchService (search_service.py - ~400 lines)
Purpose: Unified company search across multiple strategies
Primary Function: search_companies(db, query, limit=10)
Search Strategies:
- NIP/REGON Direct Lookup - Exact match on identifiers
- Synonym Expansion - Expand keywords (e.g., "strony" → www, web, portal)
- PostgreSQL FTS - Full-text search with tsvector (production)
- Fuzzy Matching - pg_trgm for typo tolerance
- SQLite Fallback - Keyword scoring (development only)
Scoring System:
- Name match: +10 points
- Services match: +8 points
- Competencies match: +7 points
- Description match: +5 points
- City match: +3 points
Configuration:
- Max Results: 10 (configurable)
- Min Score: 3 (filter low-quality matches)
- Synonyms: Defined in
SEARCH_SYNONYMSdict
Error Handling:
- PostgreSQL FTS failure → rollback + fallback to SQLite
- Empty queries → return empty list
- Invalid parameters → raise ValueError
Usage Example:
from search_service import search_companies
results = search_companies(db, "strony www", limit=10)
# Returns: List[SearchResult(company, score, match_type)]
💬 ChatService (nordabiz_chat.py - ~800 lines)
Purpose: AI chat assistant with company context
Primary Function: process_chat_message(session_id, user_message)
Key Responsibilities:
- Session Management - Create, load, and manage chat sessions
- Context Building - Find relevant companies (max 8)
- History Management - Last 10 messages per session
- AI Integration - Call Gemini API with streaming
- Token Tracking - Monitor usage and costs
Context Limits:
- Max Companies: 8 (prevents token overflow)
- Max Messages: 10 (sliding window)
- Max Tokens: ~30,000 input tokens
- Streaming: Real-time response chunks
Database Tables:
chat_sessions- Session metadatachat_messages- Message historygemini_usage- Token usage tracking
Cost Tracking:
- Input tokens × $0.075 per 1M
- Output tokens × $0.30 per 1M
- Stored in
gemini_usagetable
Example Flow:
# 1. User sends message
user_msg = "Kto robi strony www?"
# 2. Search for relevant companies
companies = search_companies(db, user_msg, limit=8)
# 3. Build context with last 10 messages
context = build_context(session, companies, history)
# 4. Call Gemini API
response = gemini_service.generate_streaming(context)
# 5. Save message and track tokens
save_message(session, user_msg, response)
track_usage(session, input_tokens, output_tokens)
🤖 GeminiService (gemini_service.py - ~500 lines)
Purpose: Google Gemini AI API integration Primary Functions:
generate_text(prompt, model="gemini-2.5-flash")generate_streaming(prompt, model="gemini-2.5-flash")analyze_image(image_path, prompt)moderate_content(text)
Supported Models:
- gemini-2.5-flash - Fast, cheap ($0.075/1M tokens)
- gemini-2.5-pro - High quality ($1.25/1M tokens)
- gemini-3-flash-preview - Experimental (free)
Key Features:
- Text Generation - Chat, content creation, analysis
- Image Analysis - Logo recognition, screenshot analysis
- Streaming Responses - Real-time output for chat
- Content Moderation - Safety filters (harassment, hate, violence)
- Cost Tracking - Token usage monitoring
Configuration:
- API Key:
GEMINI_API_KEY(from .env) - Rate Limit: 200 requests/day (free tier)
- Max Tokens: 1M input, 8K output (flash model)
- Temperature: 0.7 (default for chat)
Safety Settings:
safety_settings = {
"HARM_CATEGORY_HARASSMENT": "BLOCK_MEDIUM_AND_ABOVE",
"HARM_CATEGORY_HATE_SPEECH": "BLOCK_MEDIUM_AND_ABOVE",
"HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_MEDIUM_AND_ABOVE",
"HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_MEDIUM_AND_ABOVE",
}
Error Handling:
- API errors → retry with exponential backoff
- Rate limit exceeded → graceful degradation
- Safety block → return user-friendly error message
📧 EmailService (email_service.py - ~200 lines)
Purpose: Email notifications via Microsoft Graph API
Primary Function: send_email(to, subject, body_html)
Authentication: OAuth 2.0 (MSAL) Configuration:
- Client ID:
MS_GRAPH_CLIENT_ID - Client Secret:
MS_GRAPH_CLIENT_SECRET - Tenant ID:
MS_GRAPH_TENANT_ID - Sender:
noreply@nordabiznes.pl
Email Types:
- Email Verification - Registration confirmation
- Password Reset - Password recovery
- Payment Reminders - Membership fees
- Event Notifications - Calendar invites
- Forum Notifications - New replies
- Admin Alerts - System notifications
Template Rendering:
- Jinja2 HTML templates in
templates/emails/ - Plain text fallback for compatibility
- Inline CSS for email client support
Error Handling:
- OAuth token refresh on 401
- Retry on transient failures (5xx)
- Fallback to local logging on total failure
🏛️ KRSService (krs_api_service.py - ~300 lines)
Purpose: Polish company registry (KRS) verification
Primary Function: fetch_company_data(krs_number)
API: KRS Open API (Ministry of Justice)
Endpoint: https://api-krs.ms.gov.pl/api/krs/OdpisAktualny/{krs}
Authentication: Public API (no key required)
Data Retrieved:
- Company Name - Legal name
- NIP - Tax identification number
- REGON - Statistical number
- Address - Registered office
- Legal Form - Sp. z o.o., S.A., etc.
- Share Capital - Initial capital
- Board Members - Management names
- Shareholders - Ownership structure
Caching:
- Database table:
company_krs_data - TTL: 30 days (data rarely changes)
- Refresh on demand via admin panel
Error Handling:
- KRS not found → return None
- API timeout → retry 3 times
- Invalid KRS format → validation error
📊 GBPService (gbp_audit_service.py - ~600 lines)
Purpose: Google Business Profile auditing Primary Functions:
search_place(company_name, address)get_place_details(place_id)generate_recommendations(audit_data)
APIs Used:
- Google Places API - Place search, details, reviews
- Gemini AI - Generate improvement recommendations
Audit Metrics:
- Profile Completeness - % of filled fields
- Review Count - Number of Google reviews
- Average Rating - Star rating (1-5)
- Response Rate - % of reviews replied to
- Photo Count - Number of uploaded photos
- Verification Status - Verified vs unverified
Recommendations Generated by AI:
- Complete missing profile fields
- Respond to unanswered reviews
- Upload more photos (categories: exterior, interior, products, team)
- Improve category selection
- Add special hours (holidays, events)
- Enable messaging
Database Storage:
gbp_audits- Audit resultsgbp_recommendations- AI-generated recommendations
Cost:
- Places API: $0.017 per search, $0.017 per details call
- Gemini AI: ~$0.02 per recommendation generation
🖥️ ITService (it_audit_service.py - ~500 lines)
Purpose: IT infrastructure maturity assessment
Primary Function: calculate_maturity_score(responses)
Assessment Areas (7 domains):
- Website & Online Presence - Website quality, SEO, analytics
- Email & Communication - Professional email, collaboration tools
- Data Security - Backups, encryption, access control
- Cloud Services - Cloud adoption, SaaS usage
- Business Software - ERP, CRM, accounting tools
- IT Support - Support availability, SLA
- Digital Skills - Team training, digital literacy
Scoring:
- Level 0: No implementation (0 points)
- Level 1: Basic implementation (25 points)
- Level 2: Intermediate (50 points)
- Level 3: Advanced (75 points)
- Level 4: Excellent (100 points)
Maturity Levels:
- 0-25%: Basic - Minimal digital presence
- 26-50%: Developing - Some digital tools
- 51-75%: Advanced - Good digital infrastructure
- 76-100%: Excellent - Mature digital organization
Report Includes:
- Overall maturity score
- Domain-specific scores
- Recommendations for improvement
- Comparison to industry average
- Action plan with priorities
Database Storage:
it_infrastructure_audits- Audit resultsdigital_maturity_scores- Historical scores
4. Database Layer (36 SQLAlchemy Models)
🗄️ SQLAlchemy ORM
Location: database.py (~1,500 lines)
Purpose: Object-Relational Mapping and database abstraction
Key Features:
- Database Agnostic: PostgreSQL (production), SQLite (development)
- Connection Pooling: SQLAlchemy pool management
- Session Management: Scoped sessions per request
- Query Builder: Pythonic query construction
- Relationship Mapping: One-to-many, many-to-many, one-to-one
- Lazy Loading: Relationships loaded on demand
- Cascade Behaviors: Delete cascade, update cascade
Session Management:
# Request-scoped session (Flask integration)
@app.before_request
def create_session():
db.session = db.Session()
@app.teardown_request
def close_session(exception=None):
db.session.close()
Connection String:
# Production
DATABASE_URL = "postgresql://nordabiz_app:password@127.0.0.1:5432/nordabiz"
# Development
DATABASE_URL = "postgresql://postgres:postgres@localhost:5433/nordabiz"
📂 Domain Models (36 total)
Core Domain (5 models)
Purpose: Fundamental business entities
1. Company
- Fields: name, slug, nip, regon, krs, category, description, website, email, phone, city, address, logo_url, verified_at, data_quality_level, created_at, updated_at
- Relationships: social_media (1:N), news (1:N), photos (1:N), audits (1:N), recommendations (1:N), fees (1:N)
- Indexes: slug (unique), nip (unique), regon (unique), krs (unique), category, city
- Full-Text Search: tsvector on name, description, services, competencies
2. User
- Fields: email, password_hash, company_id, is_admin, is_active, email_verified_at, created_at, last_login_at
- Relationships: company (N:1), chat_sessions (1:N), messages_sent (1:N), messages_received (1:N), forum_topics (1:N), forum_replies (1:N)
- Indexes: email (unique), company_id, is_admin
- Authentication: bcrypt password hashing, Flask-Login integration
3. Category
- Fields: name, slug, icon, description, company_count
- Relationships: companies (1:N)
- Values: IT, Construction, Services, Production, Trade, Other
4. CompanyOwner
- Fields: company_id, name, role, shares_percent, person_url, source
- Relationships: company (N:1)
- Purpose: Track board members and shareholders (from rejestr.io)
5. SearchHistory
- Fields: user_id, query, results_count, clicked_company_id, created_at
- Relationships: user (N:1), clicked_company (N:1)
- Purpose: Search analytics and personalization
Content Domain (6 models)
Purpose: User-generated and external content
6. CompanyNews
- Fields: company_id, title, description, url, source, published_at, news_type, relevance_score, status, moderated_by, moderated_at, rejection_reason
- Relationships: company (N:1), moderator (N:1), verification (1:1)
- Status: pending, approved, rejected
- Types: news_mention, press_release, award
7. NewsVerification
- Fields: news_id, verified_by, verified_at, verification_notes, ai_confidence_score
- Relationships: news (1:1), verifier (N:1)
- Purpose: Track AI and manual verification of news
8. ForumTopic
- Fields: author_id, title, content, category, is_pinned, is_locked, view_count, reply_count, created_at, updated_at
- Relationships: author (N:1), replies (1:N)
- Categories: general, announcements, networking, help, offers
9. ForumReply
- Fields: topic_id, author_id, content, created_at, updated_at
- Relationships: topic (N:1), author (N:1)
10. ClassifiedAd
- Fields: company_id, title, description, category, price, image_url, expires_at, is_active, created_at
- Relationships: company (N:1)
- Categories: offers, requests, announcements
11. CompanyPhoto
- Fields: company_id, url, caption, category, uploaded_by, created_at
- Relationships: company (N:1), uploader (N:1)
- Categories: exterior, interior, team, products, events
Social Domain (5 models)
Purpose: Social media and community features
12. CompanySocialMedia
- Fields: company_id, platform, url, verified_at, source, is_valid, last_checked_at, check_status, page_name, followers_count
- Relationships: company (N:1), audits (1:N)
- Platforms: facebook, instagram, linkedin, youtube, tiktok, twitter
13. SocialMediaAudit
- Fields: company_id, audit_data, audit_type, audited_at
- Relationships: company (N:1)
- Types: profile_discovery, activity_check, engagement_analysis
14. SocialMediaProfile
- Fields: social_media_id, profile_data, last_fetched_at, fetch_status
- Relationships: social_media (1:1)
- Purpose: Cache profile data from APIs
15. Recommendation
- Fields: recommender_company_id, recommended_company_id, comment, rating, status, created_at, moderated_at
- Relationships: recommender (N:1), recommended (N:1)
- Status: pending, approved, rejected
16. Like
- Fields: user_id, target_type, target_id, created_at
- Relationships: user (N:1)
- Target Types: forum_topic, forum_reply, company_news, company
Audit Domain (4 models)
Purpose: SEO, GBP, and IT auditing
17. SEOMetrics
- Fields: company_id, url, seo_score, performance_score, accessibility_score, best_practices_score, pwa_score, audit_data, audited_at
- Relationships: company (N:1)
- Source: Google PageSpeed Insights API
18. GBPAudit
- Fields: company_id, place_id, audit_data, profile_completeness, review_count, average_rating, photo_count, verified_status, audited_at
- Relationships: company (N:1), recommendations (1:N)
- Source: Google Places API + Gemini AI
19. ITInfrastructureAudit
- Fields: company_id, responses, overall_score, domain_scores, recommendations, audited_at
- Relationships: company (N:1)
- Purpose: IT maturity self-assessment
20. DigitalMaturityScore
- Fields: company_id, score, level, breakdown, calculated_at
- Relationships: company (N:1)
- Levels: basic, developing, advanced, excellent
Chat Domain (3 models)
Purpose: AI chat assistant
21. ChatSession
- Fields: user_id, company_context, message_count, total_tokens, total_cost, started_at, last_message_at
- Relationships: user (N:1), messages (1:N), usage (1:N)
22. ChatMessage
- Fields: session_id, role, content, created_at
- Relationships: session (N:1)
- Roles: user, assistant, system
23. GeminiUsage
- Fields: session_id, model, input_tokens, output_tokens, total_tokens, cost, created_at
- Relationships: session (N:1)
- Purpose: Track AI usage and costs
Community Domain (5 models)
Purpose: Events, fees, messaging, notifications
24. Event
- Fields: title, description, location, start_time, end_time, organizer_id, max_attendees, rsvp_deadline, created_at
- Relationships: organizer (N:1), attendees (1:N)
25. EventAttendee
- Fields: event_id, user_id, status, rsvp_at
- Relationships: event (N:1), user (N:1)
- Status: pending, attending, declined
26. MembershipFee
- Fields: company_id, period_start, period_end, amount, status, paid_at, payment_method, notes
- Relationships: company (N:1)
- Status: pending, paid, overdue
27. Message
- Fields: sender_id, recipient_id, subject, body, is_read, read_at, created_at
- Relationships: sender (N:1), recipient (N:1)
28. Notification
- Fields: user_id, type, message, url, is_read, read_at, created_at
- Relationships: user (N:1)
- Types: new_news, news_approved, forum_reply, message_received, event_invite
System Domain (8 models)
Purpose: System management and logging
29. EmailVerification
- Fields: user_id, token, expires_at, verified_at, created_at
- Relationships: user (N:1)
30. PasswordReset
- Fields: user_id, token, expires_at, used_at, created_at
- Relationships: user (N:1)
31. APIQuota
- Fields: api_name, quota_limit, quota_used, period_start, period_end
- Purpose: Track API usage against quotas
- APIs: gemini, brave, pagespeed, places
32. APILog
- Fields: api_name, endpoint, request_data, response_status, response_time, created_at
- Purpose: API call logging and debugging
33. DataQualityCheck
- Fields: company_id, check_type, passed, issues, checked_at
- Relationships: company (N:1)
- Check Types: nip_verification, krs_verification, website_check, social_media_check
34. ActivityLog
- Fields: user_id, action, target_type, target_id, ip_address, user_agent, created_at
- Relationships: user (N:1)
- Purpose: User activity tracking
35. AuditLog
- Fields: user_id, action, target_type, target_id, changes, ip_address, created_at
- Relationships: user (N:1)
- Purpose: Admin action auditing
36. SystemSetting
- Fields: key, value, description, updated_at
- Purpose: Application configuration
- Examples: maintenance_mode, registration_enabled, chat_enabled
5. Template Rendering
📄 Jinja2 Template Engine
Location: templates/ directory
Purpose: Server-side HTML rendering
Template Structure:
templates/
├── base.html # Base template (layout)
├── components/ # Reusable components
│ ├── navbar.html
│ ├── footer.html
│ ├── company_card.html
│ └── pagination.html
├── index.html # Homepage
├── company_detail.html # Company profile
├── search_results.html # Search page
├── auth/ # Authentication pages
│ ├── login.html
│ ├── register.html
│ └── reset_password.html
├── dashboard/ # User dashboard
│ ├── dashboard.html
│ ├── chat.html
│ └── profile.html
├── admin/ # Admin pages
│ ├── seo_dashboard.html
│ ├── forum_moderation.html
│ └── users.html
├── forum/ # Forum pages
├── audit/ # Audit report pages
└── emails/ # Email templates
Template Inheritance:
{# base.html #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Norda Biznes{% endblock %}</title>
{% block extra_css %}{% endblock %}
</head>
<body>
{% include 'components/navbar.html' %}
{% block content %}{% endblock %}
{% include 'components/footer.html' %}
<script>{% block extra_js %}{% endblock %}</script>
</body>
</html>
{# company_detail.html #}
{% extends 'base.html' %}
{% block title %}{{ company.name }} - Norda Biznes{% endblock %}
{% block content %}
<h1>{{ company.name }}</h1>
<p>{{ company.description }}</p>
{% endblock %}
Common Template Variables:
current_user- Logged-in user (Flask-Login)request- Flask request objectconfig- App configurationurl_for()- URL generation functionget_flashed_messages()- Flash messages
Template Filters:
{{ company.created_at|datetimeformat }} # Format datetime
{{ company.description|truncate(200) }} # Truncate text
{{ company.name|title }} # Title case
{{ price|currency }} # Format currency
{{ url|urlize }} # Convert URLs to links
Security:
- Auto-escaping: HTML is escaped by default
- CSRF Tokens: Included in all forms via
{{ csrf_token() }} - XSS Prevention: Jinja2 auto-escapes all variables
6. Static Assets
🎨 Static File Structure
Location: static/ directory
static/
├── css/
│ ├── main.css # Main stylesheet
│ ├── admin.css # Admin panel styles
│ └── components.css # Component styles
├── js/
│ ├── main.js # Global JavaScript
│ ├── chat.js # AI chat functionality
│ ├── search.js # Search autocomplete
│ └── admin.js # Admin panel JS
├── images/
│ ├── logo.png # Site logo
│ ├── companies/ # Company logos
│ └── icons/ # UI icons
└── uploads/ # User uploads (not in Git)
├── logos/
└── photos/
CSS Framework: Custom CSS (no Bootstrap/Tailwind) JavaScript: Vanilla JS (minimal dependencies) Icons: Font Awesome or SVG icons
Key JavaScript Modules:
chat.js- WebSocket-like streaming for AI chatsearch.js- Autocomplete and instant searchadmin.js- Admin dashboard interactionsforum.js- Forum post editing and moderation
Component Interaction Patterns
Pattern 1: Public Company Search
Flow:
User → /search?q=strony www
↓
Router → PublicRoutes.search()
↓
SearchService.search_companies(db, "strony www")
↓ (synonym expansion)
SearchService → PostgreSQL FTS (tsvector search)
↓
ORM → Company model + related data
↓
PublicRoutes → Templates (search_results.html)
↓
Jinja2 → HTML response
↓
User Browser
Key Components:
- Router -
/searchroute handler - SearchService - Query processing and scoring
- Database - PostgreSQL FTS query
- Templates - Jinja2 rendering
- Static - CSS for search results
Pattern 2: AI Chat Request
Flow:
User → /api/chat/<id>/message (POST JSON)
↓
Router → APIRoutes.chat_message()
↓
Auth → Check @login_required
↓
RateLimit → Check API quota (100/day)
↓
CSRF → Validate token
↓
ChatService.process_message(session_id, message)
↓
SearchService.search_companies(db, message, limit=8)
↓
ChatService → Build context (companies + history)
↓
GeminiService.generate_streaming(prompt)
↓
Gemini API → Streaming response
↓
ChatService → Save message to DB
↓
ChatService → Track token usage
↓
JSON response → User (streaming chunks)
Key Components:
- Router -
/api/chat/<id>/messagehandler - Auth - Flask-Login authentication
- RateLimit - API quota enforcement
- ChatService - Session and context management
- SearchService - Company discovery
- GeminiService - AI integration
- Database - Message and usage storage
Pattern 3: Admin SEO Audit
Flow:
Admin → /admin/seo (GET)
↓
Router → AdminRoutes.seo_dashboard()
↓
Auth → Check current_user.is_admin
↓
ORM → Load SEOMetrics + Company data
↓
Templates → Render admin_seo_dashboard.html
↓
User clicks "Audit Company X"
↓
JavaScript → POST /api/seo/audit (AJAX)
↓
Router → APIRoutes.trigger_seo_audit()
↓
Background Script → scripts/seo_audit.py
↓
PageSpeed API → Audit URL
↓
Background Script → Parse results
↓
ORM → Insert/update SEOMetrics
↓
JSON response → Update UI
Key Components:
- Router -
/admin/seoand/api/seo/audithandlers - Auth - Admin-only access control
- Templates - Admin dashboard with AJAX
- Static - JavaScript for audit triggering
- Background Scripts - SEO audit execution
- External API - Google PageSpeed Insights
- Database - SEOMetrics storage
Pattern 4: User Registration
Flow:
User → /register (GET)
↓
Router → AuthRoutes.register()
↓
Templates → Render register.html (with CSRF token)
↓
User submits form
↓
POST /register
↓
Router → AuthRoutes.register()
↓
CSRF → Validate token
↓
RateLimit → Check registration quota (5/hour)
↓
Validation → Email, password strength, company_id
↓
ORM → Create User (bcrypt password hash)
↓
EmailVerification → Create token
↓
EmailService.send_email(verification email)
↓
MSGraph API → Send email
↓
Redirect → /login (with flash message)
Key Components:
- Router -
/registerGET and POST handlers - CSRF - Form protection
- RateLimit - Registration throttling
- ORM - User creation
- EmailService - Verification email
- External API - Microsoft Graph for email
- Templates - Registration form
Data Flow Patterns
Database Query Patterns
1. Simple Query (ORM):
# Get company by slug
company = db.session.query(Company).filter_by(slug='pixlab-sp-z-o-o').first()
2. Join Query (Relationships):
# Get company with social media
company = db.session.query(Company)\
.options(joinedload(Company.social_media))\
.filter_by(slug='pixlab-sp-z-o-o')\
.first()
3. Full-Text Search (PostgreSQL):
# Search companies by keyword
results = db.session.query(Company)\
.filter(Company.search_vector.match('strony www'))\
.order_by(desc(func.ts_rank(Company.search_vector, func.to_tsquery('strony & www'))))\
.limit(10)\
.all()
4. Aggregation Query:
# Count companies by category
category_counts = db.session.query(
Category.name,
func.count(Company.id)
).join(Company).group_by(Category.name).all()
Error Handling Patterns
1. Service Layer Error Handling:
def search_companies(db, query, limit=10):
try:
# Try PostgreSQL FTS
results = _search_fts(db, query, limit)
return results
except Exception as e:
logger.error(f"FTS search failed: {e}")
db.rollback() # CRITICAL: Rollback failed transaction
# Fallback to SQLite-style search
return _search_fallback(db, query, limit)
2. API Route Error Handling:
@app.route('/api/chat/<int:session_id>/message', methods=['POST'])
@login_required
@limiter.limit("100/day")
def chat_message(session_id):
try:
data = request.get_json()
if not data or 'message' not in data:
return jsonify({"error": "Message required"}), 400
response = chat_service.process_message(session_id, data['message'])
return jsonify({"success": True, "response": response}), 200
except ValueError as e:
return jsonify({"error": str(e)}), 400
except Exception as e:
logger.exception("Chat error")
return jsonify({"error": "Internal server error"}), 500
3. External API Error Handling:
def call_gemini_api(prompt):
max_retries = 3
retry_delay = 1 # seconds
for attempt in range(max_retries):
try:
response = genai.generate_text(prompt)
return response
except genai.RateLimitError:
logger.warning("Gemini rate limit exceeded")
return {"error": "AI service temporarily unavailable"}
except genai.APIError as e:
if attempt < max_retries - 1:
time.sleep(retry_delay * (2 ** attempt)) # Exponential backoff
continue
else:
logger.error(f"Gemini API failed: {e}")
raise
Authentication Flow
Login Flow:
1. User submits credentials → POST /login
2. Validate CSRF token
3. Query User by email
4. Verify password (bcrypt.check_password_hash)
5. Check email_verified_at (must not be null)
6. Check is_active flag
7. Flask-Login: login_user(user, remember=True)
8. Update last_login_at timestamp
9. Set session cookie (httponly, secure, samesite)
10. Redirect to /dashboard
Authorization Checks:
# Public route (no auth)
@app.route('/')
def index():
# Anyone can access
pass
# User route (requires login)
@app.route('/dashboard')
@login_required
def dashboard():
# Must be authenticated
pass
# Admin route (requires admin flag)
@app.route('/admin/users')
@login_required
def admin_users():
if not current_user.is_admin:
abort(403) # Forbidden
# Admin-only logic
pass
Configuration and Environment
Environment Variables (.env)
Required Variables:
# Flask
SECRET_KEY=<random-secret-key>
FLASK_ENV=production # or development
# Database
DATABASE_URL=postgresql://nordabiz_app:password@127.0.0.1:5432/nordabiz
# Google Gemini AI
GEMINI_API_KEY=<api-key>
# Brave Search API
BRAVE_SEARCH_API_KEY=<api-key>
# Google PageSpeed Insights
GOOGLE_PAGESPEED_API_KEY=<api-key>
# Google Places API
GOOGLE_PLACES_API_KEY=<api-key>
# Microsoft Graph API (Email)
MS_GRAPH_CLIENT_ID=<client-id>
MS_GRAPH_CLIENT_SECRET=<client-secret>
MS_GRAPH_TENANT_ID=<tenant-id>
# Rate Limiting
REDIS_URL=redis://localhost:6379/0 # Production only
# Session
SESSION_TYPE=filesystem # or redis
⚠️ SECURITY WARNING:
- NEVER commit
.envfile to Git - Use
.env.exampleas template (without actual secrets) - Production secrets stored on server only
Application Configuration (app.py)
# Flask configuration
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_POOL_SIZE'] = 10
app.config['SQLALCHEMY_MAX_OVERFLOW'] = 20
# Session configuration
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_PERMANENT'] = True
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)
# Security
app.config['WTF_CSRF_ENABLED'] = True
app.config['WTF_CSRF_TIME_LIMIT'] = None
# Rate limiting
app.config['RATELIMIT_STORAGE_URL'] = os.getenv('REDIS_URL', 'memory://')
app.config['RATELIMIT_HEADERS_ENABLED'] = True
Deployment Configuration
Gunicorn WSGI Server
systemd Service: /etc/systemd/system/nordabiznes.service
[Unit]
Description=Norda Biznes Partner
After=network.target postgresql.service
[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/var/www/nordabiznes
Environment="PATH=/var/www/nordabiznes/venv/bin"
ExecStart=/var/www/nordabiznes/venv/bin/gunicorn \
--workers 4 \
--bind 127.0.0.1:5000 \
--timeout 120 \
--access-logfile /var/log/nordabiznes/access.log \
--error-logfile /var/log/nordabiznes/error.log \
app:app
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Key Settings:
- Workers: 4 (2 × CPU cores + 1)
- Bind: 127.0.0.1:5000 (localhost only, NPM proxies from external)
- Timeout: 120 seconds (for long AI requests)
- User: www-data (non-root for security)
Service Management:
# Start service
sudo systemctl start nordabiznes
# Stop service
sudo systemctl stop nordabiznes
# Restart service
sudo systemctl restart nordabiznes
# Check status
sudo systemctl status nordabiznes
# View logs
sudo journalctl -u nordabiznes -f
Logging and Monitoring
Application Logging
Configuration:
import logging
# Production logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/nordabiznes/app.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
Log Locations:
- Application:
/var/log/nordabiznes/app.log - Gunicorn Access:
/var/log/nordabiznes/access.log - Gunicorn Error:
/var/log/nordabiznes/error.log - systemd:
journalctl -u nordabiznes
Log Levels:
- DEBUG: Development only, verbose output
- INFO: General information (startup, shutdown, API calls)
- WARNING: Degraded performance, fallback scenarios
- ERROR: Errors that don't crash the app
- CRITICAL: Errors that crash the app
Health Check Endpoint
Route: /health
Method: GET
Authentication: None (public)
Response:
{
"status": "healthy",
"database": "connected",
"timestamp": "2026-01-10T12:00:00Z",
"version": "1.0.0"
}
Usage:
- NPM health checks
- Monitoring systems (Zabbix, Prometheus)
- Uptime monitoring (UptimeRobot)
- Load balancer health checks
Security Features
1. Authentication Security
- Password Hashing: bcrypt (cost factor 12)
- Session Security: httponly, secure, samesite cookies
- Email Verification: Required before login
- Password Reset: Time-limited tokens (1 hour expiry)
- Account Lockout: (Planned) After 5 failed attempts
2. Authorization
- Three Levels: Public, User, Admin
- Decorator Pattern:
@login_required,@admin_required - Object-Level: Company owners can edit their profiles
3. Input Validation
- CSRF Protection: All POST/PUT/DELETE requests
- XSS Prevention: Jinja2 auto-escaping
- SQL Injection: SQLAlchemy parameterized queries
- File Upload: Whitelist extensions, size limits
4. API Security
- Rate Limiting: 200/day global, 100/day chat
- API Keys: Environment variables only
- CORS: Disabled by default
- HTTPS Only: All API calls to external services
5. Database Security
- Localhost Only: PostgreSQL accepts only 127.0.0.1 connections
- Password Auth: Strong passwords for DB users
- Least Privilege: Application user has limited permissions
- No Root Access: Application runs as www-data user
Related Documentation
Higher-Level Diagrams
- System Context Diagram (C4 Level 1) - External actors and systems
- Container Diagram (C4 Level 2) - Major containers and technology stack
Same-Level Diagrams
- Database Schema Diagram - (Planned) Detailed ER diagram
- External Integrations Diagram - (Planned) API integration details
Lower-Level Documentation
- Data Flow Diagrams - (Planned) Sequence diagrams for key flows
- API Endpoints Reference - (Planned) Complete API documentation
Infrastructure Documentation
- Deployment Architecture - Servers, network, ports
- Network Topology - (Planned) Network diagram
- Critical Configurations - (Planned) NPM, SSL, etc.
Analysis Documents (Phase 1)
- Flask Application Structure Analysis - Detailed code analysis
- Database Schema Analysis - Database deep dive
- External API Integrations Analysis - API details
- Data Flows Analysis - Flow documentation
Maintenance Notes
When to Update This Diagram
Update this document when:
- New routes are added to
app.py - New service modules are created
- Database models are added or significantly changed
- Major refactoring of component structure
- New external API integrations
- Authentication/authorization logic changes
What NOT to Update Here
Don't update for:
- Bug fixes that don't change architecture
- Template content changes
- CSS/JS styling updates
- Minor field additions to existing models
- Configuration value changes
Review Frequency
- Quarterly review during architecture meetings
- After major releases (version bumps)
- Before onboarding new developers
Glossary
C4 Model
- Software architecture diagramming approach with 4 levels: Context, Container, Component, Code
Flask
- Python web framework for building web applications
SQLAlchemy
- Object-Relational Mapping (ORM) library for Python
Gunicorn
- WSGI HTTP server for Python applications
WSGI
- Web Server Gateway Interface, Python web application standard
ORM
- Object-Relational Mapping, database abstraction layer
FTS
- Full-Text Search, PostgreSQL text search feature
pg_trgm
- PostgreSQL extension for fuzzy text matching using trigrams
Jinja2
- Template engine for Python (used by Flask)
bcrypt
- Password hashing algorithm
CSRF
- Cross-Site Request Forgery, web security vulnerability
XSS
- Cross-Site Scripting, web security vulnerability
Rate Limiting
- Controlling request frequency to prevent abuse
Streaming Response
- Sending response data in chunks (used for AI chat)
Document Status: ✅ Complete Last Reviewed: 2026-01-10 Next Review: 2026-04-10 (Quarterly)