Skip to content

Repository files navigation

Fincheck PME

.NET License: AGPL-3.0 version

Multi-tenant SME finance platform — banking sync, cash flow, invoices, AI insights via optional ContextMemory or a direct OpenAI-compatible LLM. Clean Architecture, .NET 9, Blazor Server, AdminLTE 4.

Contents: Run · Docker · Secrets · ContextMemory · Architecture · License

How to run

dotnet restore
dotnet build
dotnet run --project src/Fincheck.Web --urls http://localhost:5188

Open http://localhost:5188. In Development, the seeder applies migrations and creates demo data.

Docker (shared network-local network)

Fincheck does not change the docker-compose under C:\Network\infra. It starts extra containers (fincheck, keycloak) on the network-local network already used by gateway, laravox, companybrain, and so on.

# 1) Shared infra (Postgres on network-postgres)
cd C:\Network\infra
docker compose up -d

# 2) Fincheck on the same network (server Keycloak by default via .env)
cd c:\Network\_work\FinCheck\Fincheck
cp .env.example .env   # fill in secrets
docker compose up --build -d

# Optional local Keycloak (offline):
# docker compose --profile local-keycloak up -d

# Optional ContextMemory (GHCR):
# docker compose -f docker-compose.yml -f docker-compose.contextmemory.yml up --build -d
Service URL
Fincheck http://localhost:5300
Keycloak (server) https://keycloak.kortexio.io — realm fincheck, client fincheck-web
Keycloak local (profile) http://localhost:8180 (admin / admin)

Backup: remote Postgres plus Docker volumes fincheck_documents (App_Data/documents) and fincheck_data (DP keys).

If the network has another name: CM_DOCKER_NETWORK=<name> docker compose up -d.

The db-init service ensures the fincheck and keycloak databases exist on the shared Postgres when you use the local-keycloak profile.

Automatic deploy (GitHub → local Docker Desktop)

A push to main (or a manual Run workflow) deploys on this PC via a self-hosted runner.

  1. Docker Desktop running and network-infra on network-local (or the name in CM_DOCKER_NETWORK in .env).
  2. On GitHub: Settings → Actions → Runners → New self-hosted runner → Windows and copy the token.
  3. In PowerShell (in this repo):
.\scripts\setup-github-runner.ps1 -Token "PASTE_TOKEN_HERE" -Start
  1. Keep the runner window open (user session — required for Docker Desktop).
  2. Push to main or use Actions → Deploy Docker Desktop → Run workflow.

The workflow is .github/workflows/deploy-docker-desktop.yml. App: http://localhost:5300.

Tests

dotnet test

Demo login

Field Value
Email demo@fincheck.local
Password Demo!23456

Secrets (not in git)

Environment Where
Docker / deploy .env at the repo root (gitignored). The self-hosted workflow copies C:\Network\_work\FinCheck\Fincheck\.env. Template: .env.example.
Local dotnet run dotnet user-secrets on the Web project

appsettings.json must not contain passwords or API keys.

Configure user-secrets (dotnet user-secrets set ... --project src/Fincheck.Web):

Key Description
ConnectionStrings:DefaultConnection PostgreSQL (production / remote dev)
EnableBanking:ApplicationId Enable Banking application ID
EnableBanking:PrivateKeyPath Path to the JWT private key (PEM)
EnableBanking:RedirectUri OAuth callback URI (e.g. http://localhost:5188/banking/callback)
EnableBanking:WebhookSecret Optional secret for inbound webhooks
EnableBanking:AspspName / AspspCountry ASPSP sandbox (e.g. Model Bank / FI or a PT bank)
EnableBanking:UseDemo false to use the real aggregator
Email:DedicatedInboxDomain Dedicated inbox domain (invoices+{schema}@domain)
Mollie:ApiKey Mollie API key
Mollie:WebhookUrl Mollie webhook URL
Mollie:WebhookSecret Optional shared secret; when set, the webhook requires header X-Mollie-Signature (or query signature) to match. Mollie does not sign webhooks natively — this is simple anti-spoofing, not HMAC.
Mollie:UseDemo false for real payments
Email:Provider imap / gmail / outlook / demo
Email:Username IMAP/SMTP user
Email:Password IMAP password / app password
Email:SmtpHost SMTP host
Email:UseDemo false for real email
Ai:BaseUrl OpenAI-compatible host without /v1 (e.g. http://localhost:11434 or vLLM). The client calls POST {BaseUrl}/v1/chat/completions
Ai:Model Model name (e.g. qwen3.5:9b)
Ai:UseDemo false for Insights/Categorizer via LLM
Ai:TimeoutSeconds HTTP timeout for AI calls

External providers default to demo mode (Integrations:UseDemoProviders=true). AI is controlled separately by Ai:UseDemo.

ContextMemory (optional)

Financial chat and insight memory can use the ContextMemory gateway. Without a gateway, the app talks to the model via Ai:* (OpenAI-compatible) or stays in demo mode.

"ContextMemory": {
  "BaseUrl": "http://localhost:5100",
  "AppId": "fincheck",
  "ApiKey": "cm_live_…",
  "NumCtx": 32768
}
  • With BaseUrl + ApiKey: chat via POST /v1/chat/completions plus tenant wiki queries; each conversation has a sessionId in localStorage.
  • Insights stored in the DB are also upserted to the wiki (sourceId=tenant-{tenantId}).
  • Without ApiKey: chat stays on demo / direct OpenAI-compatible LLM (Ai:*).

Self-host: clone/run Kortexio/ContextMemory, or:

docker compose -f docker-compose.yml -f docker-compose.contextmemory.yml up --build -d

More detail: docs/llm-openai-compatible.md.

Docker env: CONTEXT_MEMORY_BASE_URL, CONTEXT_MEMORY_APP_ID, CONTEXT_MEMORY_API_KEY.

Enable Banking (sandbox)

  1. Create an application at Enable Banking and download the JWT private key.
  2. Configure secrets:
dotnet user-secrets set "EnableBanking:ApplicationId" "<app-id>" --project src/Fincheck.Web
dotnet user-secrets set "EnableBanking:PrivateKeyPath" "C:/secrets/enablebanking.pem" --project src/Fincheck.Web
dotnet user-secrets set "EnableBanking:RedirectUri" "http://localhost:5188/banking/callback" --project src/Fincheck.Web
dotnet user-secrets set "EnableBanking:UseDemo" "false" --project src/Fincheck.Web
dotnet user-secrets set "Integrations:UseDemoProviders" "false" --project src/Fincheck.Web
  1. In the Enable Banking console, register the redirect URI exactly as above.
  2. In Bank accounts → connect bank → after SCA the /banking/callback callback completes the session.
  3. BankConnection.ExternalConnectionId stores the session_id (survives restart). Under Consents you can sync or reconnect if the state is RequiresReauth.
  4. Webhook (optional): POST /api/webhooks/banking/{provider} with EnableBanking:WebhookSecret.

Invoice inbox

Address per tenant: invoices+{schema}@{Email:DedicatedInboxDomain}. Configure real IMAP (Email:UseDemo=false, Email:Provider=imap) on a shared mailbox; the 5‑minute job routes PDF attachments to the matching schema.

Architecture

  • Fincheck.Domain — entities, value objects, pure rules
  • Fincheck.Application — use cases (MediatR), ports, DTOs
  • Fincheck.Infrastructure — EF Core + Identity, adapters (Enable Banking / demo, OpenAI-compatible LLM / ContextMemory / demo AI, Mollie / demo, email), background jobs
  • Fincheck.Web — Blazor Server + AdminLTE 4 + Minimal APIs

Multi-tenant

Primary isolation by TenantId. On PostgreSQL, provisioning creates one schema per tenant (CREATE SCHEMA + CREATE TABLE … LIKE public.* for business tables) and TenantSchemaInterceptor sets search_path to {schema}, public. Identity / Tenants / Memberships tables stay in public.

UI modules

Dashboard · Bank accounts · Transactions · Cash flow · Categories · Invoices/review · Accounts payable · AI insights · Alerts · Reports · Team · Plan and payment · Documents · Settings (GDPR) · Admin tenants

Billing note: Fincheck charges a one-time payment via Mollie (no automatic recurring subscription or silent charge). When the paid period ends and the tenant is suspended, premium actions (bank sync, AI finance chat) stay blocked until a new payment (see IPlanGate).


Licensing

AGPL-3.0 for this open-source core (same as KYC / ContextMemory). Commercial / hosted offerings: kortexio.io. See docs/license-and-support.md and CONTRIBUTING.md.

Discoverability

Suggested GitHub topics: fintech, sme, cashflow, open-banking, csharp, dotnet, blazor, postgresql, contextmemory, multi-tenant, self-hosted, agpl, open-source, mollie, pme.

About

Multi-tenant SME finance platform - banking sync, cash flow, invoices, AI insights (ContextMemory or direct LLM). .NET 9 / Blazor. AGPL-3.0.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages