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 guideOverview
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.
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.
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).
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.
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)
| Tab | Content |
|---|---|
| Information | Company contact details and attributes. |
| Contacts | People to contact (manual add). |
| Opportunities | Open and won/lost deals for this client. |
| Subscriptions | The client's recurring contracts. |
| Invoices | Invoices issued for this client. |
| Notes | Free-form notes. |
| History | Log of actions related to the client. |
Pipeline & opportunities
The pipeline shows your sales opportunities in columns, by stage.
The stages
Lead → Prospect → Qualification → Proposal → Negotiation → Won / 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).
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.
Invoices
The Invoices module covers issuing, payment tracking, printing and PDF export. Settings (numbering, VAT, template) live in Settings › Billing.
Invoice life cycle
Statuses: Draft → Issued → Paid, 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.
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: Draft → Sent → Accepted, 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:
| Profile | Items offered |
|---|---|
| End client | The annual per-application subscriptions (EntraGUARD, AdGUARD, AzureGUARD) and the three-app suite. |
| Partner | The entry fee and the annual partner licence, plus the optional branded website (included) added at 0. |
| Standalone | The source-code licence. |
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.
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.
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).
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.
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). WinExeexecutable, assembly name CrmGUARD, root namespace CrmGUARD.- Metadata: Company=M365Expertise, Product=CrmGUARD, icon
salesguard.ico.
Code layout
| Folder | Content |
|---|---|
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:
AddColumnIfMissingadds missing columns to an already-deployed database, without data loss (noDROP COLUMN). - Integrity: foreign keys enabled, WAL journaling.
- Location stored in a preferences file; movable from the UI.
Main tables
| Table | Purpose |
|---|---|
clients | Client directory (status, priority, contact details). |
contacts | Contacts attached to a client. |
opportunities | Opportunities (stage, amount). |
subscriptions | Subscriptions (due date, amount, status, last billing). |
products | Product catalogue (type). |
invoices | Invoices and lines (details frozen at creation). |
tasks, notes, history | Tasks, notes, action log. |
company | Single 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.
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: theLocclass (singletonLoc.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). SetLangraisesPropertyChanged("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.
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 SDK —
dotnet --versionmust return10.x. - Inno Setup 6+ —
ISCC.exeis 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.iss → installer\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.
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.