GSM Application uses a two-database model. A single central database (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ti-infinite/GSMApplication/llms.txt
Use this file to discover all available pages before exploring further.
TenantRegistryDb) acts as a directory, mapping each company’s CompanyId to the SQL Server host and database where that tenant’s data lives. Every microservice connects to this registry first, resolves the tenant-specific connection string, and then opens a second connection to the correct tenant database. This pattern means each agricultural company’s data is fully isolated at the database level — no joins or queries can accidentally cross tenant boundaries.
Database Model Overview
TenantRegistryDb
One central SQL Server database, shared across all services. Contains a single
Tenants table. Services connect here to resolve dynamic connection strings.Tenant Databases
One SQL Server database per company (tenant). Each holds a
Users table with PBKDF2-hashed credentials plus any domain data for that tenant.1. Create TenantRegistryDb
Run the following SQL against your SQL Server instance using SQL Server Management Studio, Azure Data Studio, orsqlcmd. This creates the registry database and the Tenants lookup table.
The connection string in
DB_MASTER_URL must use TrustServerCertificate=True when connecting to SQL Server instances with self-signed TLS certificates. This is the default in the .env.example file. For production instances with a CA-signed certificate you may set this to False or remove the flag entirely.Tenants Table Column Reference
| Column | Type | Description |
|---|---|---|
CompanyId | NVARCHAR(50) PK | Unique identifier for the tenant. This is the value users enter at login and the companyId claim in the JWT. Examples: IH001, AG001. |
Server | NVARCHAR(255) | SQL Server host and optional port for the tenant database. Accepts any valid ADO.NET server address, e.g. 192.168.1.50,1433 or (localdb)\mssqllocaldb. |
Database | NVARCHAR(255) | Name of the tenant-specific SQL Server database on that server. |
DbUser | NVARCHAR(255) | SQL login username used to connect to the tenant database. |
DbPassword | NVARCHAR(255) | Password for the SQL login. Stored in plaintext in the registry — use a dedicated low-privilege login per tenant. |
IsActive | BIT | When 0, the tenant is disabled. Login attempts for an inactive tenant are rejected by gsmauth before any credential check. |
2. Create a Tenant Database
Each tenant needs its own database on a SQL Server instance (which can be the same instance or a different one). The minimum required schema is aUsers table. The Users table must include PasswordHash and PasswordSalt columns because gsmauth uses PBKDF2 hashing — the plain-text business columns from a legacy system are not sufficient to validate passwords.
Run the following SQL on the SQL Server instance that will host the tenant:
3. Register the Tenant
Once the tenant database exists, add a row toTenantRegistryDb.Tenants so the microservices can discover it. The example below registers a demo tenant using (localdb)\mssqllocaldb:
4. The IsActive Flag
TheIsActive column is checked by gsmauth before it attempts to resolve the tenant database connection. Setting IsActive = 0 is the recommended way to disable a tenant without deleting its data.
CompanyId, gsmauth returns a 401 Unauthorized response immediately, without connecting to the tenant database or evaluating the username and password. This makes tenant deactivation an effective emergency killswitch.
5. Verify the Setup
After provisioning, you can do a quick sanity check fromsqlcmd or any SQL client:
docker compose up --build and attempt a login via the frontend at http://localhost:3000. A successful JWT response confirms that gsmauth resolved the tenant registry correctly and connected to the tenant database.
Multi-Server Tenant Example
Because eachTenants row can specify a different Server, you can distribute tenants across SQL Server instances. The following example shows two tenants on separate hosts: