You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: dev-team/docs/standards/golang/multi-tenant.md
+42-35Lines changed: 42 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,14 +29,14 @@ This module covers multi-tenant patterns with Tenant Manager.
29
29
30
30
**Existence ≠ Compliance.** A service that has "some multi-tenant code" is NOT considered multi-tenant unless every component matches the canonical patterns defined in this document exactly.
31
31
32
-
MUST replace multi-tenant implementations that use custom middleware, manual DB switching, non-standard env var names, or any mechanism other than the lib-commons v3 tenant-manager sub-packages — they are **non-compliant**. Not patched, not adapted, **replaced**.
32
+
MUST replace multi-tenant implementations that use custom middleware, manual DB switching, non-standard env var names, or any mechanism other than the lib-commons v4 tenant-manager sub-packages — they are **non-compliant**. Not patched, not adapted, **replaced**.
33
33
34
34
The only valid multi-tenant implementation uses:
35
-
-`tenantId` from JWT via `TenantMiddleware` or `MultiPoolMiddleware` (from `lib-commons/v3/commons/tenant-manager/middleware`), registered per-route using a local `WhenEnabled` helper
36
-
-`core.ResolvePostgres` / `core.ResolveMongo` / `core.ResolveModuleDB` for database resolution (from `lib-commons/v3/commons/tenant-manager/core`)
37
-
-`valkey.GetKeyFromContext` for Redis key prefixing (from `lib-commons/v3/commons/tenant-manager/valkey`)
38
-
-`s3.GetObjectStorageKeyForTenant` for S3 key prefixing (from `lib-commons/v3/commons/tenant-manager/s3`)
39
-
-`tmrabbitmq.Manager` for RabbitMQ vhost isolation (from `lib-commons/v3/commons/tenant-manager/rabbitmq`)
35
+
-`tenantId` from JWT via `TenantMiddleware` or `MultiPoolMiddleware` (from `lib-commons/v4/commons/tenant-manager/middleware`), registered per-route using a local `WhenEnabled` helper
36
+
-`core.ResolvePostgres` / `core.ResolveMongo` / `core.ResolveModuleDB` for database resolution (from `lib-commons/v4/commons/tenant-manager/core`)
37
+
-`valkey.GetKeyFromContext` for Redis key prefixing (from `lib-commons/v4/commons/tenant-manager/valkey`)
38
+
-`s3.GetObjectStorageKeyForTenant` for S3 key prefixing (from `lib-commons/v4/commons/tenant-manager/s3`)
39
+
-`tmrabbitmq.Manager` for RabbitMQ vhost isolation (from `lib-commons/v4/commons/tenant-manager/rabbitmq`)
40
40
- The 8 canonical `MULTI_TENANT_*` environment variables with correct names and defaults
41
41
-`client.WithCircuitBreaker` on the Tenant Manager HTTP client
42
42
-`client.WithServiceAPIKey` on the Tenant Manager HTTP client for `/settings` endpoint authentication
@@ -53,7 +53,7 @@ These are the only files that require multi-tenant changes. The exact paths foll
53
53
54
54
| File | Gate | What Changes |
55
55
|------|------|-------------|
56
-
|`go.mod`| 2 | lib-commons v3, lib-auth v2 |
56
+
|`go.mod`| 2 | lib-commons v4, lib-auth v2 |
57
57
|`internal/bootstrap/config.go`| 3 | 8 canonical `MULTI_TENANT_*` env vars in Config struct |
|`internal/bootstrap/routes.go` (or equivalent router file) | 4 | Per-route composition via `WhenEnabled(ttHandler)` — auth validates JWT before tenant resolves DB. Each project implements the `WhenEnabled` helper locally. See [Route-Level Auth-Before-Tenant Ordering](#route-level-auth-before-tenant-ordering-mandatory)|
@@ -96,31 +96,38 @@ These are the only files that require multi-tenant changes. The exact paths foll
96
96
|`docs/multi-tenant-guide.md`| Activation guide: env vars, how to enable/disable, verification steps |
97
97
|`docs/multi-tenant-preview.html`| Visual implementation preview (generated at Gate 1.5, kept for reference) |
98
98
99
-
**HARD GATE: Files outside this map that contain multi-tenant logic are non-compliant.** If a service has custom files like `internal/tenant/resolver.go`, `internal/middleware/tenant_middleware.go`, `pkg/multitenancy/pool.go` or similar — these MUST be removed and replaced with the canonical lib-commons v3 tenant-manager sub-packages wired through the files listed above.
99
+
**HARD GATE: Files outside this map that contain multi-tenant logic are non-compliant.** If a service has custom files like `internal/tenant/resolver.go`, `internal/middleware/tenant_middleware.go`, `pkg/multitenancy/pool.go` or similar — these MUST be removed and replaced with the canonical lib-commons v4 tenant-manager sub-packages wired through the files listed above.
100
100
101
101
### Required lib-commons Version
102
102
103
-
Multi-tenant support requires **lib-commons v3** (`github.com/LerianStudio/lib-commons/v3`). The `tenant-manager` package does not exist in v2.
103
+
Multi-tenant support requires **lib-commons v4** (`github.com/LerianStudio/lib-commons/v4`). The `tenant-manager` package does not exist in v2.
104
104
105
105
| lib-commons version | Multi-tenant support | Package path |
|**v2** (`lib-commons/v2`) | Not available | N/A — no `tenant-manager` package |
108
-
|**v3** (`lib-commons/v3`) | Full support |`github.com/LerianStudio/lib-commons/v3/commons/tenant-manager/...` (sub-packages: `core`, `client`, `postgres`, `mongo`, `middleware`, `rabbitmq`, `consumer`, `valkey`, `s3`). The `middleware` sub-package contains both `TenantMiddleware` (single-module) and `MultiPoolMiddleware` (multi-module). Route-level composition uses a local `WhenEnabled` helper (not from lib-commons). |
108
+
|**v3** (`lib-commons/v3`) | Legacy | Same sub-packages as v4 but without `tenant-manager/cache`. Upgrade to v4. |
109
+
|**v4** (`lib-commons/v4`) | Full support (current) |`github.com/LerianStudio/lib-commons/v4/commons/tenant-manager/...` (sub-packages: `core`, `client`, `cache`, `postgres`, `mongo`, `middleware`, `rabbitmq`, `consumer`, `valkey`, `s3`). The `middleware` sub-package contains both `TenantMiddleware` (single-module) and `MultiPoolMiddleware` (multi-module). Route-level composition uses a local `WhenEnabled` helper (not from lib-commons). |
109
110
110
-
**Migration from v2 to v3:**
111
+
**Migration to v4:**
111
112
112
-
Services currently on lib-commons v2 MUST upgrade to v3 before implementing multi-tenant. The upgrade involves:
113
+
Services on lib-commons v2 or v3 MUST upgrade to v4 before implementing multi-tenant. The upgrade involves:
The `ConsumerTrigger` interface is defined in the lib-commons middleware package. Services that process messages in multi-tenant mode implement this interface and pass it to the middleware for lazy consumer activation.
560
567
561
568
```go
562
-
// Defined in github.com/LerianStudio/lib-commons/v3/commons/tenant-manager/middleware
569
+
// Defined in github.com/LerianStudio/lib-commons/v4/commons/tenant-manager/middleware
@@ -572,7 +579,7 @@ The middleware calls `EnsureConsumerStarted` after extracting the tenant ID. The
572
579
The `ErrorMapper` type lets you customize how tenant-manager errors are converted into HTTP responses. When not set, the built-in default mapper handles standard cases (401, 403, 404, 503).
573
580
574
581
```go
575
-
// Defined in github.com/LerianStudio/lib-commons/v3/commons/tenant-manager/middleware
582
+
// Defined in github.com/LerianStudio/lib-commons/v4/commons/tenant-manager/middleware
| "Service already has multi-tenant code" | Existence ≠ compliance. Code that doesn't match the Ring canonical model (lib-commons v3 tenant-manager sub-packages) is non-compliant and MUST be replaced entirely. |**STOP. Run compliance audit against this document. Replace every non-compliant component.**|
1251
-
| "Our custom multi-tenant approach works" | Working ≠ compliant. Custom implementations create drift, block lib-commons upgrades, prevent standardized tooling, and cannot be validated by automated compliance checks. |**STOP. Replace with canonical lib-commons v3 implementation.**|
1257
+
| "Service already has multi-tenant code" | Existence ≠ compliance. Code that doesn't match the Ring canonical model (lib-commons v4 tenant-manager sub-packages) is non-compliant and MUST be replaced entirely. |**STOP. Run compliance audit against this document. Replace every non-compliant component.**|
1258
+
| "Our custom multi-tenant approach works" | Working ≠ compliant. Custom implementations create drift, block lib-commons upgrades, prevent standardized tooling, and cannot be validated by automated compliance checks. |**STOP. Replace with canonical lib-commons v4 implementation.**|
1252
1259
| "Just need to adapt/patch the existing code" | Non-standard implementations cannot be patched into compliance. The patterns are structurally different (context-based resolution vs static connections, lib-commons middleware vs custom middleware). |**STOP. Replace, do not patch.**|
1253
1260
| "We only have one customer" | Requirements change. Multi-tenant is easy to add now, hard later. |**Design for multi-tenant, deploy as single**|
1254
1261
| "Tenant Manager adds complexity" | Complexity is in connection management anyway. Tenant Manager standardizes it. |**Use Tenant Manager for multi-tenant**|
@@ -1911,7 +1918,7 @@ When `MULTI_TENANT_ENABLED=true`, each tenant has its own M2M credentials stored
MANDATORY: Multi-tenant dual-mode applies to all Go services (no exceptions). Gate 0 implements dual-mode from the start using lib-commons v3 resolvers. Gate 0.5G verifies compliance. This detection captures the CURRENT state of the codebase for context.
1785
+
MANDATORY: Multi-tenant dual-mode applies to all Go services (no exceptions). Gate 0 implements dual-mode from the start using lib-commons v4 resolvers. Gate 0.5G verifies compliance. This detection captures the CURRENT state of the codebase for context.
1786
1786
1787
1787
See [multi-tenant.md](../../docs/standards/golang/multi-tenant.md) for the canonical model and [dev-delivery-verification](../dev-delivery-verification/SKILL.md) Step 3.5G for the verification checks.
This check only applies to Go backend services. It verifies that all resource access uses lib-commons v3 resolvers (which work transparently in both single-tenant and multi-tenant mode).
563
+
This check only applies to Go backend services. It verifies that all resource access uses lib-commons v4 resolvers (which work transparently in both single-tenant and multi-tenant mode).
## ⛔ Multi-Tenant Dual-Mode Implementation (Go backend only — skip for TypeScript/Frontend)
404
404
405
405
**Applies only when `language == "go"`.** TypeScript and frontend projects have different patterns.
406
406
407
-
All Go backend code must work in BOTH modes from the start. The lib-commons v3 resolvers handle both transparently — in single-tenant mode they return the default connection, in multi-tenant mode they resolve per-tenant. There is NO post-cycle adaptation step.
407
+
All Go backend code must work in BOTH modes from the start. The lib-commons v4 resolvers handle both transparently — in single-tenant mode they return the default connection, in multi-tenant mode they resolve per-tenant. There is NO post-cycle adaptation step.
0 commit comments