Complete guide

CrmGUARD / CrmGUARD

Sales operations for the GUARD suite: clients, opportunities, subscriptions and invoices. Desktop app, offline, single-seat.

Version 1.38.0 · User, installation & technical guide

Overview

CrmGUARD is a desktop application that centralises the sales operations of the GUARD suite: clients, opportunities, subscriptions and invoices. It runs offline, with no server, on a local database.

At a glance

  • Windows desktop app (WPF, .NET 10) — installed on the machine, no browser.
  • Local SQLite database (salesguard.db) created automatically on first launch. No server setup.
  • Single-seat: one user, data on their own machine. Automatic timestamped backups.
  • Bilingual French / English, instant switch with no restart.
  • Built-in invoicing with automatic numbering, VAT, printable templates and PDF export.

Who it is for

CrmGUARD is the sales cockpit for the GUARD suite. It suits a publisher distributing its software, a partner reselling it under their own brand, or a sales team running its own activity.

How to read this guide

The left menu follows the chapter order: getting started and installation, then each feature step by step, then the technical part (architecture and database) and finally deployment. Use the search box to filter chapters, and the FR / EN switch at the top to change language.

First launch

On the very first run, the app sets itself up: it creates the database, lets you pick the language.

The splash screen appears

A “CRM GUARD” screen shows while the local database is created and migrated. It is instant on a recent machine.

The database is created automatically

The salesguard.db file is created in the application data folder. Nothing to install or configure.

Choose the language

The app starts in English by default. Switch to French with the FR / EN selector at the top of the sidebar — the change is instant.

Screen: Dark sidebar on the left (app name at the top, FR/EN selector just below, menu in the middle, full-width red “Close” button at the very bottom). Light content area on the right.

Finding your way

The screen has two parts: the sidebar (navigation) and the content area.

The sidebar

  • Top: the app name and tagline (customisable), then the FR / EN selector.
  • Middle: the menu. Some entries are collapsible groups (Clients, Invoices, Settings) — click the label to expand.
  • Very bottom: the red Close button (full width) that quits the app.
  • The button at the top collapses the sidebar to enlarge the workspace; a button brings it back.

The menu, in order

EntryPurpose
DashboardOverview: key figures, charts, due dates.
ClientsClient directory and detail sheets.
PipelineSales opportunities in a kanban view.
SubscriptionsRecurring contracts and renewals.
Invoices / ArchivedInvoicing, issuing, payment tracking.
TasksSales to-do with priorities and due dates.
ProductsCatalogue of offers.
HistoryLog of every action.
Settings › DatabaseStatus, backups, database location.
Settings › My detailsYour company details.
Settings › BillingNumbering, VAT, invoice template.
AboutVersion, environment, name/tagline customisation.

Keyboard shortcuts

Depending on the open screen:

  • Ctrl + F — focus the search box.
  • Ctrl + N — create a new item (client, invoice…).
  • Esc — go back (close a sheet).

Installation

Two ways to install CrmGUARD on a machine: the Windows installer (recommended) or running the published executable directly.

Machine requirements

  • Windows 64-bit (Windows 10 or 11).
  • .NET Desktop Runtime 10 (x64) — required for the lightweight edition. The installer checks for it and offers to download it if missing: dotnet.microsoft.com/download/dotnet/10.0/runtime (“Run desktop apps” section).

Method 1 — the installer (recommended)

Run CrmGUARD-Setup-<version>.exe

It requests administrator rights (install into C:\Program Files\CrmGUARD).

Accept the licence agreement

The agreement is shown before installation.

Choose shortcuts

A Start-menu shortcut is created; the Desktop shortcut is optional (checkbox).

Runtime check

If .NET Desktop Runtime 10 is missing, the setup opens the Microsoft download page and stops — install the runtime, then run the setup again.

Done

The app launches from the Start menu. The salesguard.db database is created on first launch.

Clean uninstall: an entry is added to “Apps & features”. The database and backups, located in user data, are not removed by uninstalling.

Method 2 — standalone edition (no runtime)

A “standalone” edition bundles .NET: larger, but it runs without installing the runtime. It is produced with the dedicated build option (see the Build & deploy chapter).

The database is created automatically on first launch, next to the executable or in the application data. No server setup is required.

Dashboard

The dashboard is the home page: it summarises sales activity at a glance.

What you see

  • Key figures: open pipeline, revenue, upcoming renewals, overdue tasks.
  • Revenue by product: revenue split as a donut.
  • Won revenue trend: a bar chart of the last 12 months (months with no sale show as zero).
  • Opportunities: a shortcut to the pipeline.
Collapsible banners: each card has a clickable header (▼ / ▶) to collapse it. The chart redraws automatically when you expand it.
Screen: White cards stacked on a light background. Key figures at the top, then the “Revenue by product” donut, the monthly trend bars and the opportunities block with an “Open the pipeline” button.

Clients

The Clients module manages your directory and, for each client, a detailed tabbed sheet.

The client list

  • Search at the top, filters (status, priority) and pagination (25 / 50 / 100 / 200 per page) for large volumes.
  • Sort by clicking a column header (an arrow shows the direction).
  • CSV import and CSV export: export produces the whole directory; import reads that same format (“;” separator).

Statuses & priorities

Client status: Prospect, Active, Inactive. Priority: Low, Normal, High. These colour-coded values are translated on display according to the language.

Create a client

Click “New”

Or Ctrl+N from the list.

Fill in the sheet

Legal name (required), contact details, status, priority. The legal name is the only required field.

Save

The client appears in the list and becomes available everywhere (opportunities, invoices, subscriptions).

The client sheet (8 tabs)

TabContent
InformationCompany contact details and attributes.
ContactsPeople to contact (manual add).
OpportunitiesOpen and won/lost deals for this client.
SubscriptionsThe client's recurring contracts.
InvoicesInvoices issued for this client.
NotesFree-form notes.
HistoryLog of actions related to the client.
Esc closes the sheet and returns to the list.

Pipeline & opportunities

The pipeline shows your sales opportunities in columns, by stage.

The stages

LeadProspectQualificationProposalNegotiationWon / Lost. Each column groups the opportunities at that stage.

Create and track an opportunity

New opportunity

Attach it to a client, give it a title, an amount and a starting stage.

Move it forward

Change its stage as talks progress. The view reflects the change immediately.

Close as “Won”

A won opportunity feeds dashboard revenue and can trigger an automatic invoice (see Billing).

The amount of won opportunities feeds the “Won revenue trend” chart on the dashboard.

Subscriptions

Subscriptions represent recurring contracts: start date, renewal date, amount, renewal.

Subscription fields

  • The client and product involved.
  • Start and renewal date; days left are computed automatically (a cancelled subscription shows “—”).
  • Amount and auto-renewal.
  • Status: Active / Cancelled.

Search, filter, pagination

The list can be searched (client, product), filtered by status and paginated like the other lists.

Automatic billing: at the renewal date, the app can create a draft invoice for the subscription (depending on the billing setting). This check runs at startup then every hour — see the Billing chapter.

Invoices

The Invoices module covers issuing, payment tracking, printing and PDF export. Settings (numbering, VAT, template) live in Settings › Billing.

Invoice life cycle

Statuses: DraftIssuedPaid, or Cancelled. An issued invoice past its due date is flagged Overdue.

Create an invoice

New invoice

Select the client; their details are frozen onto the invoice at creation time.

Add lines

Description, quantity, unit price. Subtotal, VAT and gross total are computed automatically.

Issue

The invoice gets its number (prefix + year + counter) and moves to “Issued”.

Track payment

Mark “Paid” on receipt. Overdue unpaid invoices surface as “Overdue”.

Remind, print, export

  • ✉ Remind: prepares a pre-filled reminder email (number, amount, due date, days overdue) to the client's address.
  • Preview: opens the invoice in the browser, ready to print.
  • ⤓ Export PDF: opens the invoice with the print dialog, choose “Save as PDF”.

Archived invoices

The Invoices › Archived entry keeps invoices out of the current flow, viewable at any time.

Four layout templates are available (banner, classic, compact, clean) — chosen in Settings › Billing.

Quotes & purchase orders

The Quotes module produces a quote that serves as a purchase order once signed: the printable document carries an “Agreed and accepted” signature block. It shares the numbering, VAT and four layout templates of invoices, set in Settings › Billing.

Commercial profile

Each quote is tied to a profile that adapts the catalogue shown and the document heading: End client, Partner or Standalone. The profile is chosen at the top of the quote; it determines the items shown in the catalogue (see below).

Quote life cycle

Statuses: DraftSentAccepted, or Refused. A sent quote past its validity date is flagged Expired. An accepted quote can be converted into an invoice.

Create a quote

New quote

Select the client; their details are frozen onto the quote at creation time. Choose the profile (end client, partner, standalone) and the validity date.

Tick the items

The Catalogue panel shows only the items for the chosen profile, with their price. Tick the lines you want, then click Add ticked lines: they fill the grid, where quantities and prices remain editable.

Adjust

Add free-form lines if needed. Subtotal, VAT and gross total are computed automatically.

Issue

The quote gets its number (prefix + year + counter, separate from invoices) and moves to “Sent”.

The catalogue by profile

The items offered come from the Products module, filtered by the profile's channel:

ProfileItems offered
End clientThe annual per-application subscriptions (EntraGUARD, AdGUARD, AzureGUARD) and the three-app suite.
PartnerThe entry fee and the annual partner licence, plus the optional branded website (included) added at 0.
StandaloneThe source-code licence.
The catalogue and prices are managed in the Products module. A profile's items are recognised by their code prefix (CF- / PART- / AUTO-).

Agreed and accepted

The quote serves as a purchase order: the printable document includes an Agreed and accepted signature block (date, name and title, signature) with the handwritten wording to copy. The client orders by returning the document dated and signed.

Preview, PDF, conversion

  • Preview: opens the quote in the browser, ready to print.
  • ⤓ Export PDF: opens the quote with the print dialog, choose “Save as PDF”.
  • Convert to invoice: from an accepted quote, creates a draft invoice mirroring the client, lines and VAT. Both documents stay linked; the invoice is reviewed before issuing.

Archived quotes

The Quotes › Archived entry keeps quotes out of the current flow, viewable at any time. A CSV export of the list is available.

The document is produced in the application's language (French or English): switch the language before preview or export to obtain a quote in the client's language.

Tasks, products, history

Tasks

A simple sales to-do, with priority and due date.

  • Search (title, client), filter by priority (Low / Normal / High), “Show completed” checkbox.
  • Sort by due date or state; pagination for long lists.
  • Tick a task to mark it done.

Products

The catalogue of offers you sell.

  • Each product has a code, a name, a description and a type: One-off audit, Licence, Subscription.
  • Search (code, name) and filter by type.
  • Products feed opportunities, subscriptions and invoice lines.

History

The log of every action recorded in the app.

  • Full-text search (detail, action, object), filter by object type.
  • Useful to find when a client, invoice or opportunity was changed.

Settings: company & billing

My details (company)

Your company details, reused on invoices.

  • Legal name, legal form, capital, address, identifiers (VAT, trade register…), contact details, bank details, logo, legal footer.
  • The legal name is required to save.

Billing

Your invoice configuration, on a dedicated page that fills the space.

  • Automatic billing and its trigger: when an opportunity is won, when a subscription is due, or both.
  • Invoice template: banner, classic, compact or clean (list with preview).
  • Numbering: prefix, next number, preview of the full next number.
  • VAT, currency, payment terms, late fees, early-payment discount.
  • Preview: generates a sample invoice with your settings.
Important: “My details” and “Billing” write to the same company record, but each page only saves its own fields — editing one never overwrites the other's data.
When automatic billing is on, the app creates a draft at the due date; nothing is issued automatically. You complete and issue the draft from Invoices.

Settings: database

This page manages the health, backup and location of your local database.

Database status

A coloured banner shows the state: the whole card is green when the database is connected at launch, red on error.

Automatic backup

  • On by default: a timestamped copy of the database is made at every startup, before any write.
  • Configurable rotation: number of copies to keep (3 / 5 / 10 / 20 / 30 / 50).
  • List of existing backups (date + size), Open folder and Restore selection buttons.

Location

The Change location button moves the database to another folder (for example a synced folder).

Backup settings are stored in a small separate preferences file, not in the database itself — sensible, since it is the database that gets copied.

Customisation (name & tagline)

You can replace the name and tagline shown by the app, from About.

Open “About”

A standalone menu entry. The “Customisation” card is at the bottom (collapsible banners).

Enter the name and tagline

Leave empty to keep the defaults (“CrmGUARD” / “CRM GUARD”).

Apply

The top of the sidebar updates immediately; the splash screen picks up this name on the next launch.

The name and tagline are stored in the company record (local database), with automatic migration of your existing database.
Handy for a partner distributing the app under their own brand.

Technical architecture

CrmGUARD is a single-seat WPF (.NET 10) application backed by SQLite. No network layer, no server.

Overview

UI (WPF / XAML)               Views/*.xaml (+ .xaml.cs)
        │                     MainWindow (navigation, overlays)
        ▼
Services / business logic     Services/*.cs
        │                     Repo (partial), Loc, InvoiceRenderer…
        ▼
Data (local SQLite)           salesguard.db  ·  Services/Db.cs

Tech stack

  • .NET 10, net10.0-windows, WPF (UseWPF).
  • SQLite via Microsoft.Data.Sqlite (10.0.0).
  • WinExe executable, assembly name CrmGUARD, root namespace CrmGUARD.
  • Metadata: Company=M365Expertise, Product=CrmGUARD, icon salesguard.ico.

Code layout

FolderContent
Models/Entities and reference data: Company, Invoice, Entities (clients/opportunities/…), Licensing, Countries, Sectors.
Services/Data access and logic: Repo (partial class per domain), Db (schema + migrations), InvoiceRenderer, AutoInvoice, Loc (i18n), RefConverter.
Views/23 XAML views + code-behind (one per screen) + Pager, IQuickActions helpers.
Tests/Standalone console test project (excluded from the app build).
installer/Inno Setup script, build, icon.

The MainWindow pattern

  • Centralised navigation: Navigate(page) instantiates the view and marks the active menu entry. Views are recreated on each navigation.
  • In-house dialogs (no system popups): Confirm/Ask and Notify/Toast overlays (Info / Success / Error).
  • Auto-invoicing: an hourly timer sweeps due subscriptions (idempotent).

Database

All data lives in a single SQLite file, salesguard.db, managed by Services/Db.cs.

Principles

  • Auto-created schema on first launch (CREATE TABLE IF NOT EXISTS).
  • Tolerant migrations: AddColumnIfMissing adds missing columns to an already-deployed database, without data loss (no DROP COLUMN).
  • Integrity: foreign keys enabled, WAL journaling.
  • Location stored in a preferences file; movable from the UI.

Main tables

TablePurpose
clientsClient directory (status, priority, contact details).
contactsContacts attached to a client.
opportunitiesOpportunities (stage, amount).
subscriptionsSubscriptions (due date, amount, status, last billing).
productsProduct catalogue (type).
invoicesInvoices and lines (details frozen at creation).
tasks, notes, historyTasks, notes, action log.
companySingle company record (id=1) + billing settings + custom name/tagline.

Access layer

The Repo is a partial class split by domain (RepoClients, RepoInvoices, RepoCompany…), with shared helpers in Repo.cs. The public API stays Repo.Xxx.

Internal rule: the company record rewrites the whole row. Any view editing only part of the company sheet (My details, Billing, Customisation) starts from a fresh read and rewrites only its fields — never overwriting the rest.

Bilingual (i18n)

The app is fully bilingual FR/EN with hot switching, no restart and no satellite files.

Mechanism: an in-house dictionary

  • Services/Loc.cs: the Loc class (singleton Loc.I, INotifyPropertyChanged).
  • A bindable indexer this[key] returns the FR or EN string for the current language (or the key itself if missing, to spot gaps).
  • SetLang raises PropertyChanged("Item[]")all bound labels re-evaluate instantly.
  • The setting is stored in a preferences file (English by default).

Usage in code

<!-- XAML -->
<TextBlock Text="{Binding [Nav.Dashboard], Source={x:Static svc:Loc.I}}"/>

// Code-behind
string title = Loc.T("CB.Saved");

With the namespace xmlns:svc="clr-namespace:CrmGUARD.Services" in the view header.

Reference data translated without breakage

Reference values (statuses, priorities, stages…) stay stored and compared in French; only display is translated, via Loc.Ref(value) and a RefConverter applied to columns and lists. Code comparisons (== "Payée") therefore remain unchanged.

To extend: controls whose text is written by code (dynamic titles, messages) are not bound in XAML — they are translated via Loc.T at the source.

Build & deploy

The installer is produced from the project root, with the .NET 10 SDK and Inno Setup.

Build requirements

  • .NET 10 SDKdotnet --version must return 10.x.
  • Inno Setup 6+ISCC.exe is found automatically at its usual location.

Build the installer

powershell -ExecutionPolicy Bypass -File installer\build.ps1

The script chains: dotnet publish to win-x64 (framework-dependent) → installer\publish\, then compiles CrmGUARD.issinstaller\dist\CrmGUARD-Setup-<version>.exe.

Standalone edition (bundles .NET)

powershell -ExecutionPolicy Bypass -File installer\build.ps1 -SelfContained

What the installer does

  • Installs into C:\Program Files\CrmGUARD (admin rights), Start-menu shortcut + optional desktop shortcut.
  • Clean uninstall entry in “Apps & features”.
  • Checks the .NET Desktop Runtime 10 in the registry; if missing, opens the Microsoft page and stops.
  • Shows the licence agreement before installing.

Version number

The version comes from <Version> in CrmGUARD.csproj; the installer reads it from the published DLL (single source). The installer's AppId (GUID) must never change: it is the key for updates and uninstalls.

Tests

cd Tests
dotnet run

Standalone console project (no external dependency) covering pure logic (invoice maths, subscriptions, company, reference data). It runs anywhere and returns an error code if a test fails; it is excluded from the app build.

Client machine: for the framework-dependent edition, install the .NET Desktop Runtime 10 (x64) (“Run desktop apps” section). The database is created on first launch, no server setup.
Build note: after extracting a project archive, purge obj/ and bin/ before compiling. A build.ps1 at the root does this and checks the .xaml/.xaml.cs pairing.

Troubleshooting & FAQ

Frequently asked questions

Where is my data?

In the salesguard.db file (application data), with timestamped backups in a subfolder. The location can be changed from Settings › Database.

The “Database status” banner is red

The database could not open at startup. Check the location (accessible folder, not read-only) and disk space. Restore a backup if needed.

“Save” rejects my client / company sheet

The legal name is required. Fill it in and try again.

Can I switch language at any time?

Yes, the FR/EN selector switches the whole UI instantly, with no restart.

How do I back up before a risky change?

A backup is made at every startup. You can also open the backups folder from Settings › Database and copy the desired file.

On first build of the source code

If compilation fails with a “type not found” error on a single type, the archive was probably extracted partially: purge obj/ and bin/ and rebuild. The root build.ps1 automates this cleanup.