🎯 A comprehensive Progressive Web App (PWA) for analyzing Ukrainian financial statements with AI-powered insights, built with Blazor WebAssembly and optimized for performance with AOT compilation.
| Host | URL | Status |
|---|---|---|
| GitHub Pages | whitewaw.github.io | |
| Netlify | ua-finance.netlify.app |
- Overview
- Features
- AI Assistant
- Technology Stack
- Getting Started
- Project Structure
- Financial Analysis Features
- Contributing
- Deployment
- License
This application provides a powerful, browser-based tool for comprehensive analysis of Ukrainian financial statements. Built with modern web technologies, it runs entirely in the browser using WebAssembly - no server required!
- ✅ AI-Powered - Built-in AI assistant using Chrome's Gemini Nano (100% local, private)
- ✅ Offline-first - Works without internet after initial load
- ✅ Privacy-focused - All calculations happen in your browser
- ✅ No installation - Just open and use
- ✅ Multi-language - 15-language UI and SEO-indexable landing intro (ordered by Ukraine economic importance)
- ✅ Professional-grade - 17 comprehensive financial analysis tables + 7 interactive charts
- ✅ Open Source - Free to use, modify, and contribute
Revolutionary AI-powered financial analysis running 100% in your browser!
- 🧠 Powered by Gemini Nano - Google's lightweight AI model built into Chrome
- 🔒 100% Private - No data sent to servers, everything runs locally
- 💬 Conversational Interface - Chat naturally about your financial data
- 📊 Context-Aware - AI has full access to your company's financial data
- 🌍 Multi-Language - Responds in 15 languages automatically
- ⚡ Streaming Responses - Real-time AI answers with stop control
- 📈 Smart Analysis - Calculates ratios, identifies trends, provides recommendations
- Financial Health - Comprehensive 9-section health assessment
- Get Recommendations - 4-tier prioritized action plan (Urgent → Long-term)
- Explain Key Ratios - 11 financial ratios calculated and explained
- ✅ Answer financial questions using your actual data
- ✅ Calculate any financial ratio on demand
- ✅ Explain trends and changes year-over-year
- ✅ Provide actionable recommendations with timelines
- ✅ Identify risks and suggest mitigation strategies
- ✅ Compare against industry benchmarks
- ✅ Natural conversation in 15 supported languages
- Google Chrome 127+ with Prompt API enabled
- Automatic Gemini Nano model download (first use)
- No API keys, subscriptions, or cloud services required
Learn more about Chrome AI setup →
- Characteristics of Capital - Capital structure and efficiency
- Indicators of Turnover of Current Assets - Asset velocity analysis
- Factors Affecting Turnover of Working Capital - Detailed impact analysis
- Indicators of Efficiency of Working Capital - ROI and productivity
- Availability and Movement of Fixed Assets - Asset lifecycle tracking
- Indicators of State and Movement of Fixed Assets - Quality metrics
- Calculation of Efficiency of Fixed Assets - Performance ratios
- Factor Analysis of Fixed Assets - Multifactor impact study
- Efficiency of Intangible Assets - IP and goodwill analysis
- Sources of Capital Formation - Funding sources breakdown
- Assessment of Receivables and Payables - Credit management
- Indicators of Business Activity - Operational efficiency
- Liquidity Indicators of Balance - Short-term solvency
- Solvency Ratios - Long-term financial health
- Indicators of Financial Stability - Financial stability ratios
- General Indicators of Financial Stability - Overall stability metrics
- Classification of Financial Stability Types - Risk categorization
- Composition of Assets (Base & Current) - Asset structure visualization
- Sources of Capital Formation (Base & Current) - Capital sources pie charts
- Structure of Accounts Payable (Base & Current) - Liability breakdown
- Working Capital Turnover Time - Efficiency trends
Ordered by importance for Ukraine's economy:
| # | Flag | Language | Reason |
|---|---|---|---|
| 1 | 🇺🇦 | Ukrainian (Українська) | Native |
| 2 | 🇺🇸 | English | International business |
| 3 | 🇵🇱 | Polish (Polski) | Neighbor, largest diaspora |
| 4 | 🇷🇴 | Romanian (Română) | Neighbor |
| 5 | 🇭🇺 | Hungarian (Magyar) | Neighbor |
| 6 | 🇨🇿 | Czech (Čeština) | Neighbor region |
| 7 | 🇩🇪 | German (Deutsch) | Major EU trade partner |
| 8 | 🇳🇱 | Dutch (Nederlands) | EU partner (Rotterdam port) |
| 9 | 🇫🇷 | French (Français) | EU partner |
| 10 | 🇮🇹 | Italian (Italiano) | EU partner |
| 11 | 🇪🇸 | Spanish (Español) | EU partner |
| 12 | 🇹🇷 | Turkish (Türkçe) | Black Sea partner |
| 13 | 🇨🇳 | Chinese (简体中文) | Growing trade |
| 14 | 🇯🇵 | Japanese (日本語) | Technology & investment |
| 15 | 🇷🇺 | Russian (Русский) | Historical context (last due to current situation) |
- Local Storage - Save your data securely in browser
- Import/Export - JSON-based data portability
- Sample Data - Pre-loaded examples for learning
- Auto-Save - Never lose your work
- AOT Compilation - Ahead-of-time compiled for maximum speed
- PWA Support - Install as standalone app
- Optimized Bundle - Compressed and trimmed for fast loading
- Service Worker - Offline caching for instant access
- .NET 10 - Latest performance improvements
| Technology | Version | Purpose |
|---|---|---|
| .NET | 10.0 | Runtime and SDK |
| Blazor WebAssembly | 10.0 | UI Framework |
| C# | 14.0 | Programming Language |
| Radzen Blazor | 9.1.0 | UI Component Library |
| Blazor-ApexCharts | 6.1.0 | AOT-Compatible Charts |
| Bootstrap | 5.3 | CSS Framework (local, offline PWA) |
| Chrome AI | Gemini Nano | Local AI Assistant |
| WebAssembly | SIMD | Execution Environment |
| Meziantou.Analyzer | 3.0.22 | Code Analysis |
| SonarAnalyzer | 10.20.0 | Code Quality |
| Roslynator | 4.15.0 | Refactoring & Analysis |
- ✅ AOT (Ahead-of-Time) Compilation
- ✅ WASM SIMD for faster math calculations
- ✅ WASM Deduplication for smaller bundle
- ✅ IL Trimming for smaller bundles (
TrimMode=partial) - ✅ Brotli Compression
- ✅ Native WASM optimization (
-Ozcompile and link) - ✅ .NET 10 performance enhancements
- ✅ Full ICU globalization data - required for startup-time dynamic culture
switching across 15 languages.
HybridGlobalizationis incompatible with this pattern in .NET 10 (culture must not change after runtime init). - ✅ BCL feature switches -
UseSystemResourceKeys,XmlResolverIsNetworkingEnabledByDefault=false,BuiltInComInteropSupport=false,AutoreleasePoolSupport=false,EnableCppCLIHostActivation=false,EnableUnsafeUTF7Encoding=false - ✅ Symbol-map stripping -
WasmEmitSymbolMap=falseguarantees no.symbolsfiles ship - ✅ Heap pre-reservation -
EmccMaximumHeapSize=2 GiBlets the linker pre-allocate a tight segment - ✅ AOT-safe JSON serialization (source-generated, reflection disabled)
- ✅ AOT-safe charts (ApexCharts with lambda expressions, no reflection)
- ✅ AOT-safe events (EventHandler pattern, no dynamic delegates)
- ✅ AOT-safe regex (GeneratedRegex with timeout and ExplicitCapture)
- ✅ Runtime feature switches - Disabled unused features (EventSource, StartupHook, etc.)
- ✅ Comprehensive code analyzers (Meziantou, SonarQube, Roslynator)
- ✅ Nullable reference types enabled
- ✅ Code style enforcement in build
┌─────────────────────────────────────────────────────────────────┐
│ BLAZOR WASM EXECUTION │
├─────────────────────────────────────────────────────────────────┤
│ ✅ AOT Compilation - IL → WebAssembly at build time │
│ ✅ WASM SIMD - ~20-30% faster math operations │
│ ✅ WASM Dedup - Removes duplicate WASM code │
│ ✅ IL Stripping - Removes unused IL after AOT │
│ ✅ Size Optimization - Emscripten -Oz (compile & link) │
│ ✅ Full ICU - Required for 15-language dynamic switch │
│ ✅ BCL Feature Switches - UseSystemResourceKeys, no XML net, etc│
│ ✅ WasmEmitSymbolMap - false — no .symbols files in deploy │
│ ✅ Service Worker - Offline-first caching │
│ ✅ Exception Handling - Optimized WASM exception handling │
│ ✅ JSON Serialization - Source-generated, reflection disabled │
│ ✅ Charts - ApexCharts with AOT-safe lambdas │
│ ✅ Events - EventHandler pattern (AOT-safe) │
│ ✅ Regex - GeneratedRegex (compile-time) │
│ ✅ No HTTP Diagnostics- HttpActivityPropagation disabled │
│ ✅ No EventSource - EventSource tracing disabled │
│ ✅ Feature Switches - Unused runtime features disabled │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ CODE ANALYZERS │
├─────────────────────────────────────────────────────────────────┤
│ ✅ Meziantou.Analyzer - Best practices & security │
│ ✅ SonarAnalyzer.CSharp - Code smells & bugs │
│ ✅ Roslynator - 500+ code analysis rules │
│ ✅ Nullable Reference - Null safety enabled │
│ ✅ EnforceCodeStyle - Consistent code formatting │
│ ✅ IsAotCompatible - AOT compatibility validation │
│ ✅ IsTrimmable - Trimming compatibility validation │
│ ✅ TreatWarningsAsErrors- Zero tolerance for warnings │
│ ✅ Clean Build - 0 warnings, 0 errors, 0 suppressions │
├─────────────────────────────────────────────────────────────────┤
│ AOT-SAFE PATTERNS IMPLEMENTED │
├─────────────────────────────────────────────────────────────────┤
│ ✅ [LoggerMessage] - Source-generated high-perf logging │
│ ✅ [GeneratedRegex] - Compile-time regex generation │
│ ✅ [JsonSerializable] - Source-generated JSON serialization │
│ ✅ sealed classes - All DI services sealed for perf │
│ ✅ private constructors - Utility classes non-instantiable │
│ ✅ covariant interfaces - Proper variance annotations │
│ ✅ GC.SuppressFinalize - Proper dispose pattern │
│ ✅ Custom exceptions - AIServiceException (no reserved) │
│ ✅ ConfigureAwait(false)- Async best practices │
│ ✅ IReadOnlyList<T> - Immutable collection returns │
├─────────────────────────────────────────────────────────────────┤
│ DRY PRINCIPLES (Don't Repeat Yourself) │
├─────────────────────────────────────────────────────────────────┤
│ ✅ ChartDataHelper - Shared chart operations │
│ ✅ AIAnalysisHelper - Shared AI analysis methods │
│ ✅ CalculatePercentage - Centralized percentage calculations │
│ ✅ FormatResponse - Single AI response formatter │
│ ✅ 24 components refact - Reduced ~4,500 lines of duplication │
└─────────────────────────────────────────────────────────────────┘
- .NET 10 SDK
- Any modern browser (Chrome 127+ recommended for AI features)
- (Optional) Visual Studio 2022 or VS Code
-
Clone the repository
git clone https://github.com/whitewAw/Assessment-of-Ukrainian-financial-statements.git cd Assessment-of-Ukrainian-financial-statements -
Restore dependencies
dotnet restore
-
Install WebAssembly workload
dotnet workload install wasm-tools
-
Run the application
dotnet run --project AFS
-
Open in browser
https://localhost:7157
To use the AI Assistant features:
- Use Chrome 127 or later
- Enable Prompt API: Visit
chrome://flags/#prompt-api-for-gemini-nano - Set to "Enabled" and restart Chrome
- First launch: Model downloads automatically (may take a few minutes)
dotnet publish AFS/AFS.csproj -c Release -o publishAssessment-of-Ukrainian-financial-statements/
├── 📂 AFS/ # Main Blazor WebAssembly app
│ ├── Program.cs # Application entry point
│ ├── App.razor # Root component with router
│ ├── _Imports.razor # Global using directives
│ ├── Pages/ # Page components
│ │ └── AIAssistant.razor # AI Assistant page
│ ├── Shared/ # Shared layout components
│ │ └── MainLayout.razor # Main application layout
│ └── wwwroot/ # Static assets
│ ├── js/
│ │ ├── chromeai.js # Chrome AI JavaScript interop
│ │ ├── seo-manager.js # Dynamic SEO management
│ │ ├── app.js # Blazor startup & configuration
│ │ ├── utils.js # Utility functions
│ │ ├── performance.js # Performance monitoring
│ │ ├── mobile-detection.js # Mobile device detection
│ │ └── service-worker-init.js # PWA service worker
│ ├── css/
│ │ ├── app.css # Main application styles
│ │ ├── dark-theme.css # Dark mode styles
│ │ └── radzen-dark-theme.css # Radzen dark mode overrides
│ ├── index.html # Application shell (multi-host)
│ ├── 404.html # SPA fallback page
│ └── [hosting configs] # robots.txt, sitemap.xml, etc.
│
├── 📂 AFS.ComponentLibrary/ # Reusable UI components
│ ├── Components/
│ │ ├── AIFinancialChatComponent.razor # AI chat UI
│ │ ├── Form1Component.razor # Balance sheet input form
│ │ ├── Form2Component.razor # Income statement input form
│ │ ├── NavMenu.razor # Navigation menu
│ │ ├── ThemeToggle.razor # Dark/light mode toggle
│ │ ├── CultureSelector.razor # Language selector
│ │ ├── SeoHead.razor # Per-route <PageTitle>, meta description & H1
│ │ ├── Charts/ # 7 interactive chart components
│ │ ├── Tables/ # 17 financial analysis tables
│ │ ├── TableComponents/ # Shared table elements (Td, Th, Tr)
│ │ ├── ChartsComponents/ # Shared chart elements
│ │ └── YearSelectComponents/ # Year selection dropdowns
│ ├── Helpers/
│ │ └── ApexChartsHelper.cs # AOT-safe chart configuration
│ └── Resources/ # Localization files (7 languages)
│ └── Resource.*.resx # uk, en, de, es, fr, pl, ru
│
├── 📂 AFS.Core/ # Business logic & services
│ ├── Models/ # Data models
│ │ ├── AfsModel.cs # Main application model
│ │ ├── AfsConstraints.cs # Application constants
│ │ ├── Form1.cs # Balance sheet model
│ │ ├── Form2.cs # Income statement model
│ │ ├── ChartDataItem.cs # Chart data models
│ │ └── TablsModels/ # Table-specific models
│ ├── Services/ # Business services
│ │ ├── DataCalculations/ # 40+ financial calculation services
│ │ ├── BrowserAIFinancialAdvisor.cs # Chrome AI service (sealed)
│ │ ├── OpenAIFinancialAdvisor.cs # OpenAI service (sealed)
│ │ ├── LocalStorageModelHandler.cs # Model persistence (sealed)
│ │ ├── LocalStorageCultureHandler.cs # Culture persistence (sealed)
│ │ ├── AppThemeService.cs # Theme management (sealed)
│ │ ├── JsInterop.cs # JavaScript interop (sealed)
│ │ ├── Log.cs # High-perf logging ([LoggerMessage])
│ │ └── UnicodeConverter.cs # Unicode helpers ([GeneratedRegex])
│ ├── Interfaces/ # 12 interface files
│ │ ├── IAIFinancialAdvisor.cs # AI service interface
│ │ ├── IHasBeginEnd.cs # Base interface
│ │ ├── IHasBaseCurrent.cs # Covariant interface (out T)
│ │ ├── ICapitalSourceMetric.cs # Capital metrics interface
│ │ └── ... # Other financial interfaces
│ ├── Exceptions/
│ │ └── AIServiceException.cs # Custom AI exception (AOT-safe)
│ ├── Components/
│ │ └── PageSeoHelper.cs # SEO management helper
│ └── Json/ # AOT-safe JSON serialization (60+ files)
│ ├── AfsJsonSerializerContext.cs # Source-generated serializers (85+ types)
│ ├── FinancialContextData.cs # Financial context DTO
│ ├── BusinessActivityData.cs # Business activity DTO
│ ├── SolvencyRatiosData.cs # Solvency ratios DTO
│ └── ... # 50+ individual DTO files
│
├── 📂 .github/ # GitHub configuration
│ ├── workflows/ # CI/CD workflows
│ │ └── main.yml # Deployment workflow (incl. prerender)
│ └── ISSUE_TEMPLATE/ # Issue templates
│
├── 📂 tools/ # Build-time tooling
│ └── prerender/ # Headless-Chromium prerender for SEO
│ ├── prerender.mjs # Captures rendered HTML per route
│ ├── generate-og-image.mjs # 1200x630 OG/Twitter image generator
│ └── package.json # puppeteer devDep
│
├── 📄 BROWSER_AI_SETUP.md # AI setup instructions
├── 📄 CONTRIBUTING.md # Contribution guidelines
├── 📄 CODE_OF_CONDUCT.md # Community standards
├── 📄 Directory.Build.props # Shared build settings & analyzers
├── 📄 nuget.config # NuGet package sources
├── 📄 LICENSE # MIT License
└── 📄 README.md # This file
The project uses a centralized build configuration:
Directory.Build.props - Shared settings for all projects:
- Nullable reference types enabled
- Implicit usings enabled
- Code analysis with latest rules (Meziantou, Sonar, Roslynator)
- Code style enforcement in build
IsAotCompatibleandIsTrimmablefor AOT/trimming safetyTreatWarningsAsErrorsenabled (zero tolerance policy)- Zero warning suppressions (all analyzer rules satisfied)
nuget.config - Package source configuration:
- Uses only official NuGet.org source
- Ensures consistent builds for all contributors
- Avoids conflicts with user-specific NuGet configurations
TrimmerRootAssembly (in AFS.csproj) - IL Trimmer configuration:
- Preserves
AFS.ComponentLibraryfor Blazor Router component discovery - Preserves
Microsoft.Extensions.Localizationfor resource loading - Other assemblies trimmed based on usage analysis (optimized for size)
The application supports localization through .NET resource files. Follow these steps to add a new language:
Create a new resource file in AFS.ComponentLibrary/Resources/:
Resource.{lang-code}.resx
Examples:
Resource.pl.resx(Polish)Resource.it.resx(Italian)Resource.pt.resx(Portuguese)
Tip: Copy an existing file (e.g.,
Resource.en.resx) and translate all values.
Edit AFS.ComponentLibrary/Components/CultureSelector.razor:
- Add to display data dictionary (around line 24):
private static readonly Dictionary<string, (string Flag, string NativeName)> cultureDisplayData = new()
{
["en"] = ("🇺🇸", "English"),
["uk-UA"] = ("🇺🇦", "Українська"),
// ... existing languages ...
["xx"] = ("🇽🇽", "Native Name") // Add your language
};- Add to supported cultures array (around line 34):
private static readonly CultureInfo[] supportedCultures =
[
CultureInfo.GetCultureInfo("en"),
CultureInfo.GetCultureInfo("uk-UA"),
// ... existing languages ...
CultureInfo.GetCultureInfo("xx") // Add your language code
];Edit AFS.Core/Models/AfsConstraints.cs to add AI response language:
public static string GetLanguageInstruction()
{
var cultureName = System.Globalization.CultureInfo.CurrentUICulture.Name;
return cultureName[..2].ToLowerInvariant() switch
{
"uk" => "Ukrainian",
"en" => "English",
"de" => "German",
"es" => "Spanish",
"fr" => "French",
"pl" => "Polish",
"ru" => "Russian",
"xx" => "YourLanguage", // Add your language
_ => "English"
};
}Update README.md:
- Update language count in the Overview section
- Add the new language to the Internationalization list
| Language | Code | Flag | Native Name |
|---|---|---|---|
| Ukrainian | uk-UA |
🇺🇦 | Українська |
| English | en |
🇺🇸 | English |
| German | de |
🇩🇪 | Deutsch |
| Spanish | es |
🇪🇸 | Español |
| French | fr |
🇫🇷 | Français |
| Polish | pl |
🇵🇱 | Polski |
| Russian | ru |
🇷🇺 | Русский |
- Use Ukrainian as the base -
Resource.resxcontains the authoritative Ukrainian text - Adapt, don't just translate - Use proper financial terminology for each language
- Preserve placeholders - Keep
{0},{1}, etc. in the same positions - Keep formatting - Preserve XML entities like
<,>, etc. - Test thoroughly - Check all pages after adding translations
Ask the AI anything about your financial data:
Example Questions:
- "What's my current ratio and how does it compare to benchmarks?"
- "Why did my profitability decrease this year?"
- "What are the top 3 risks in my financial position?"
- "How can I improve my working capital efficiency?"
- "Calculate my ROE and explain what it means"
- "Compare my performance against last year"
AI provides:
- ✅ Direct answers using your actual financial data
- ✅ Calculations with formulas shown
- ✅ Year-over-year trend analysis
- ✅ Risk assessments (High/Medium/Low)
- ✅ Specific actionable recommendations
- ✅ Timeline and success metrics
- Asset composition and structure
- Current vs. Non-current assets
- Equity and liabilities analysis
- Year-over-year comparisons
- Beginning and ending balances
- Revenue analysis
- Operating expenses breakdown
- Net profit calculations
- Profitability trends
- Prior period comparisons
- Current Ratio
- Quick Ratio
- Cash Ratio
- Working Capital
- Asset Liquidity Grouping
- Debt-to-Equity Ratio
- Interest Coverage
- Financial Leverage
- Solvency Recovery/Loss Ratio
- Long-term debt capacity
- Asset Turnover
- Receivables Turnover
- Inventory Turnover
- Payables Turnover
- Operating Cycle Analysis
- Autonomy Coefficient
- Financial Independence
- Capital Structure Analysis
- Stability Classification
- 4-tier stability levels
- Return on Assets (ROA)
- Return on Equity (ROE)
- Working Capital Efficiency
- Fixed Assets Productivity
- Intangible Assets ROI
- 📊 Pie charts for composition analysis
- 📈 Line charts for trend analysis
- 📉 Bar charts for comparative data
- 🎯 Donut charts for proportions
- 🔄 Real-time chart updates
We welcome contributions from the community! Whether you're fixing bugs, adding features, improving documentation, or translating to new languages - every contribution helps.
- Read CONTRIBUTING.md
- Check CODE_OF_CONDUCT.md
- Look for good first issues
- Fork, code, and submit a PR!
- 🐛 Report bugs - Create an issue
- 💡 Suggest features - Request a feature
- 🌍 Add translations - Help support more languages
- 📝 Improve docs - Documentation is always appreciated
- 💻 Submit PRs - Fix bugs or implement features
- 🤖 Enhance AI - Improve prompts and AI interactions
The application supports simultaneous deployment to multiple hosting platforms with automatic URL configuration:
| Host | Base Path | SPA Routing | Canonical | Auto-Configured |
|---|---|---|---|---|
Netlify (ua-finance.netlify.app) |
/ |
_redirects |
⭐ Primary | ✅ |
| GitHub Pages | /Assessment-of-Ukrainian-financial-statements/ |
404.html redirect |
→ Netlify | ✅ |
| Localhost | / |
Dev server | → Netlify | ✅ |
Why one canonical? Both deployments serve identical content. To prevent Google from splitting search ranking signals across two duplicate URLs, every page emits
<link rel="canonical" href="https://ua-finance.netlify.app/...">regardless of host — consolidating link equity into a single indexable URL.
The app automatically detects the hostname and configures:
- ✅ Base path for Blazor routing
- ✅ SPA routing (direct URL access works!)
- ✅ Canonical URLs for SEO
- ✅ hreflang links for multi-language
- ✅ JSON-LD structured data
- ✅ Sitemap and robots.txt
- ✅ OpenGraph and Twitter Card meta tags
- ✅ Dynamic page titles and descriptions
Supported Hosts:
┌──────────────────────────────────────────────────────────────────┐
│ Host │ Base URL │
├──────────────────────────────┼──────────────────────────────────┤
│ whitewaw.github.io │ /Assessment-of-Ukrainian-... │
│ ua-finance.netlify.app │ / │
│ localhost │ / │
└──────────────────────────────┴──────────────────────────────────┘
Deployment is automated via GitHub Actions on push to main branch.
Workflow Features:
- .NET 10 with AOT compilation
- WASM SIMD enabled for faster calculations
- WebAssembly optimization (
-Oz) - IL stripping for smaller bundles
- Service worker hash fixing
- Automatic base path handling
- Brotli compression
- Build-time prerender (Puppeteer + headless Chromium) of every route
in
sitemap.xml, so non-JS crawlers (Bing, Yandex, GPTBot, ClaudeBot, PerplexityBot, social-preview bots) receive fully rendered HTML
The same GitHub Actions workflow that publishes to gh-pages also pushes a
pristine, un-base-rewritten copy of the build to a separate netlify-deploy
branch. Netlify is connected to that branch instead of main, so it never has
to build .NET itself and it always gets <base href="/" /> (the GH Pages sed
rewrite only touches the release/ copy destined for gh-pages).
One-time Netlify setup:
- In the Netlify dashboard: Site settings → Build & deploy → Continuous deployment
- Set Production branch to
netlify-deploy - Leave the build command empty (Netlify just serves the pre-built artifact)
- Publish directory:
/(repo root of the branch)
Why a dedicated branch? Netlify and GitHub Pages need different absolute
URLs baked into the HTML (/ vs /Assessment-of-Ukrainian-financial-statements/)
and different canonical hosts inside sitemap.xml / robots.txt. Building the
artifact once and publishing two differently-rewritten copies to two branches
is cheaper and more reliable than letting Netlify run its own .NET build.
Netlify-specific pieces still in the source tree:
netlify.tomlwith SPA-redirect + security headers (applies to the branch content)_headersgenerated by the workflow (no forcedContent-Encoding— Netlify auto-negotiates Brotli/gzip, forcing it causedERR_CONTENT_DECODING_FAILED)_redirectsfor the/ai-assistantalias and SPA fallback
# Build the project
dotnet publish AFS/AFS.csproj -c Release -o release
# For GitHub Pages - update base path
sed -i 's|<base href="/" />|<base href="/your-repo-name/" />|g' \
release/wwwroot/index.html
# Deploy release/wwwroot to your hosting provider- Azure Static Web Apps - Guide
- Netlify - Simply drag & drop
wwwrootfolder - Vercel - Connect your GitHub repository
- Firebase Hosting - Use Firebase CLI
- Any static hosting - Upload
wwwrootcontents
UFIN is a Blazor WebAssembly SPA, which is a notoriously hard target for search engines (most crawlers do not execute JavaScript). The repo ships a defence-in-depth SEO setup so the app remains discoverable on Google, Bing, Yandex, DuckDuckGo, and modern AI search engines.
- Visible pre-hydration hero in
index.html(H1, description, feature grid, deep-link navigation) — prevents Google’s Soft-404 classifier from flagging the page as thin content while Blazor WASM is still loading. Blazor replaces it on hydration so users never see it after load. - Single canonical host:
https://ua-finance.netlify.app/(no duplicate-content split) - Comprehensive Open Graph + Twitter Card meta
- 6 JSON-LD blocks:
WebApplication,SoftwareApplication,FAQPage,Organization,BreadcrumbList,WebSitewithSearchAction - 15
hreflangalternates (one per supported language) +x-default sitemap.xmlships with canonical (Netlify) URLs. The GitHub Actions workflow rewrites every occurrence ofhttps://ua-finance.netlify.app/tohttps://whitewaw.github.io/Assessment-of-Ukrainian-financial-statements/inside thegh-pagescopy (same sed pattern as the<base>tag), so each host advertises its own URLs while<link rel="canonical">still consolidates all equity to Netlify.robots.txtexplicitly allow-listing modern AI crawlers:GPTBot,OAI-SearchBot,ChatGPT-User,ClaudeBot,Claude-Web,anthropic-ai,PerplexityBot,Perplexity-User,Google-Extended,Applebot,Applebot-Extended,Amazonbot,Meta-ExternalAgent,MistralAI-User,YouBot,cohere-ai,DuckAssistBot
- Service worker registered with
updateViaCache: 'none'soservice-worker.jsitself is never served from the HTTP cache — guarantees users pick up a new deploy on their next visit, not 24 hours later. manifest.jsonscreenshots[]intentionally empty until real 1280×720 screenshots exist (Chrome rejects under-sized entries and falls back to the minimal install card).
The <SeoHead> component (AFS.ComponentLibrary) emits a route-specific
<PageTitle>, <meta name="description">, OG/Twitter overrides, and an
optional <h1> (defaults to sr-only so it indexes without altering layout):
<SeoHead Title="Liquidity Ratios Calculator | UFIN"
Description="Free liquidity analysis of a Ukrainian balance sheet..."
Heading="Liquidity Ratios" />Puppeteer crawls every URL in sitemap.xml, waits for Blazor to hydrate,
and writes <route>/index.html snapshots into the published wwwroot.
Non-JS crawlers consequently see real HTML — not just the loading spinner.
Generate the social-share image any time:
cd tools/prerender
npm install
node generate-og-image.mjs ../../AFS/wwwroot/og-image.pngAn empty slot is reserved in index.html:
<meta name="google-site-verification" content="" />Paste the token from Google Search Console
and Bing Webmaster Tools, then submit
https://ua-finance.netlify.app/sitemap.xml.
- Live Application
- Chrome AI Setup Guide
- User Manual (coming soon)
- Blazor WebAssembly Docs
- .NET 10 What's New
- Chrome AI API
- Radzen Blazor Components
- Ukrainian Accounting Standards
- ✅ No data collection - All processing happens locally
- ✅ No server communication - Fully client-side application
- ✅ Secure storage - Browser's local storage only
- ✅ AI privacy - Gemini Nano runs 100% in your browser
- ✅ No API keys - No cloud services or subscriptions needed
- ✅ Open source - Fully auditable code
- ✅ Regular updates - Active maintenance and security patches
- 🔒 Zero data leaves your device - AI runs entirely in Chrome
- 🔒 No internet required - Works offline after model download
- 🔒 No analytics - Your financial data is never tracked
- 🔒 No cloud costs - Free forever, no subscriptions
- 🔒 You control the data - Delete anytime, nothing stored externally
- Blazor - Microsoft's web framework
- Radzen - Blazor UI component library
- Blazor-ApexCharts - AOT-compatible chart library
- Chrome AI - Google's built-in AI
- Gemini Nano - Lightweight AI model
- Open Iconic - Icon set
- Ukrainian accounting standards and practices
- Financial analysis methodologies
- Community feedback and contributions
- Modern AI-assisted development
This project is licensed under the MIT License - see the LICENSE file for details.
- ✅ Free to use commercially
- ✅ Free to modify and distribute
- ✅ Free to use privately
- ✅ Must include license and copyright notice
- 💬 GitHub Discussions - Ask questions
- 🐛 Issues - Report bugs
- 📧 Contact maintainers - See GitHub profile
- 🤖 AI Setup Help - Troubleshooting
- ⭐ Star this repository
- 👀 Watch for releases
- 🔔 Follow for updates
- Multi-language support (15 languages)
- 17 comprehensive financial analysis tables
- 7 interactive charts
- PWA with offline support
- AOT compilation optimization
- Automated CI/CD deployment
- Component-based architecture
- Dark theme support
- AI Assistant with Chrome AI
- Gemini Nano integration
- Context-aware financial analysis
- Streaming AI responses
- .NET 10 migration
- WASM SIMD for faster calculations
- Multi-host deployment (GitHub Pages + Netlify)
- SEO optimization for Google Search
- SPA routing for direct URL access
- AOT-safe charts (ApexCharts)
- Zero-reflection JSON serialization
- Code quality analyzers (Meziantou, SonarQube, Roslynator)
- Enhanced AI prompts and training
- Unit test coverage
- End-to-end testing
- Enhanced mobile responsiveness
- PDF report generation with AI summaries
- Excel export/import
- Historical data comparison (multi-year)
- Advanced forecasting tools (AI-powered)
- Multi-company analysis
- Cloud synchronization (optional)
- AI-powered anomaly detection
- Custom AI training on user data
- Voice commands for AI assistant
Technical SEO is complete (sitemap, hreflang ×15, JSON-LD, prerender, localized landing intro). Search-engine visibility, however, is downstream of authority signals (backlinks, brand searches, custom domain) — none of which can be solved in code. Items below are in rough order of impact, biggest first:
- Custom domain (e.g.
ufin.com.ua,ua-finance.com,bilans.ua) — $10–30/yr. The single biggest trust signal upgrade.*.netlify.appis treated as low-trust by Google. After registration: point CNAME at Netlify, enable HTTPS, then update<base href>rewrites in.github/workflows/main.yml, all<loc>entries insitemap.xml, theCANONICALconstant inindex.html, the JSON-LD@idURLs, and theSitemap:line inrobots.txt. - Backlinks from Ukrainian accounting / fintech / university sites — even 5–10 quality inbound links would 10× ranking ability for Ukrainian queries. Outreach targets: KNEU / KPI / Lviv Polytechnic accounting faculties, Habr Ukrainian-language post, DOU.ua project showcase, Reddit
r/ukraine/r/Ukrainian, accounting Telegram channels, IFA Ukraine, Ukrainian Bar Association tax-law section. - Long-form content per ratio — turn each calculator route into an SEO landing page:
@page "/articles/current-ratio-explained"with formula, examples, Ukrainian industry benchmarks, link to calculator. ≈ 18 routes × 15 languages × 800 words. This is exactly whatbuhgalter.com.uaanddtkt.com.uado to dominate Ukrainian finance SERPs. Could be partially automated using the existing AI Assistant prompt infrastructure. - Submit to directories: ProductHunt launch, AlternativeTo (under accounting/finance), FreeCodeCamp catalog, Awesome Blazor PR, Awesome WASM PR, Awesome Ukrainian Open Source PR, Chrome AI gallery submission (you ship Gemini Nano integration — they're actively curating).
Realistic timeline if all four are pursued:
| Effort | Expected outcome (Ukrainian market) |
|---|---|
| Custom domain only | +20–40% trust; minor ranking lift |
| + 5–10 backlinks | Top-10 for ~30–80 long-tail queries (3–6 months) |
| + 20 article pages | Top-3 for many long-tails, top-10 for some head terms (6–12 months) |
| + directory submissions | One-time traffic spikes (500–5000 visits per launch), some sticky brand searches |
- 17 Financial Analysis Tables
- 7 Interactive Charts
- 15 Languages Supported
- 100% Client-Side Processing
- 0 Server Dependencies
- 0 Data Collection
- ∞ Privacy Protection
Contributions make the open-source community an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated!
See CONTRIBUTING.md for ways to get started.
- All contributors and community members
- Chrome AI team for built-in AI capabilities
- .NET and Blazor teams for amazing framework
- Radzen team for excellent components
- Ukrainian developers and financial analysts
Made with ❤️ and 🤖 AI by the community
Report Bug · Request Feature · Contribute · AI Setup
🚀 Now with AI-Powered Financial Analysis!