up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
This commit is contained in:
@@ -1,12 +1,121 @@
|
||||
# Notifier Tenancy Prep — PREP-NOTIFY-TEN-48-001
|
||||
|
||||
Status: Draft (2025-11-20)
|
||||
Status: Implemented (2025-11-27)
|
||||
Owners: Notifications Service Guild
|
||||
Scope: Tenancy model and DAL/routes for Notifier (depends on Notifier II sprint).
|
||||
Scope: Tenancy model and DAL/routes for tenant context in Notifier WebService.
|
||||
|
||||
## Needs
|
||||
- Tenancy model decision; DAL/routes for tenant context in Notifier WebService.
|
||||
- Alignment with Notifier II scope (Sprint 0172).
|
||||
## Overview
|
||||
|
||||
## Handoff
|
||||
Use as prep artefact; update when tenancy model is published.
|
||||
Tenant scoping for the Notifier module ensures that rules, templates, incidents, and channels
|
||||
are isolated per tenant with proper row-level security (RLS) in MongoDB storage.
|
||||
|
||||
## Implementation Summary
|
||||
|
||||
### 1. Tenant Context Service (`src/Notifier/StellaOps.Notifier.Worker/Tenancy/`)
|
||||
|
||||
- **TenantContext.cs**: AsyncLocal-based context propagation for tenant ID and actor
|
||||
- **TenantServiceExtensions.cs**: DI registration and configuration options
|
||||
- **ITenantAccessor**: Interface for accessing tenant from HTTP context
|
||||
|
||||
Key pattern:
|
||||
```csharp
|
||||
// Set tenant context for async scope
|
||||
using var scope = tenantContext.SetContext(tenantId, actor);
|
||||
await ProcessEventAsync();
|
||||
|
||||
// Or with extension method
|
||||
await tenantContext.WithTenantAsync(tenantId, actor, async () =>
|
||||
{
|
||||
await ProcessNotificationAsync();
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Incident Repository (`src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/`)
|
||||
|
||||
New files:
|
||||
- **Repositories/INotifyIncidentRepository.cs**: Repository interface for incident persistence
|
||||
- **Repositories/NotifyIncidentRepository.cs**: MongoDB implementation with tenant filtering
|
||||
- **Serialization/NotifyIncidentDocumentMapper.cs**: BSON serialization for incidents
|
||||
|
||||
Key features:
|
||||
- All queries include mandatory `tenantId` filter
|
||||
- Document IDs use `{tenantId}:{resourceId}` composite pattern for RLS
|
||||
- Correlation key lookup scoped to tenant
|
||||
- Soft delete support with `deletedAt` field
|
||||
|
||||
### 3. MongoDB Indexes (tenant-scoped)
|
||||
|
||||
Added in `EnsureNotifyIndexesMigration.cs`:
|
||||
```javascript
|
||||
// incidents collection
|
||||
{ tenantId: 1, status: 1, lastOccurrence: -1 } // Status filtering
|
||||
{ tenantId: 1, correlationKey: 1, status: 1 } // Correlation lookup
|
||||
```
|
||||
|
||||
### 4. Existing Tenancy Infrastructure
|
||||
|
||||
The following was already in place:
|
||||
- All models have `TenantId` property (NotifyRule, NotifyChannel, NotifyTemplate, etc.)
|
||||
- Repository interfaces take `tenantId` as parameter
|
||||
- Endpoints extract tenant from `X-StellaOps-Tenant` header
|
||||
- MongoDB document IDs use tenant-prefixed composite keys
|
||||
|
||||
## Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"Notifier": {
|
||||
"Tenant": {
|
||||
"TenantIdHeader": "X-StellaOps-Tenant",
|
||||
"ActorHeader": "X-StellaOps-Actor",
|
||||
"RequireTenant": true,
|
||||
"DefaultActor": "system",
|
||||
"ExcludedPaths": ["/health", "/ready", "/metrics", "/openapi"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### HTTP API
|
||||
```http
|
||||
GET /api/v2/rules HTTP/1.1
|
||||
X-StellaOps-Tenant: tenant-123
|
||||
X-StellaOps-Actor: user@example.com
|
||||
```
|
||||
|
||||
### Worker Processing
|
||||
```csharp
|
||||
public class NotificationProcessor
|
||||
{
|
||||
private readonly ITenantContext _tenantContext;
|
||||
|
||||
public async Task ProcessAsync(NotifyEvent @event)
|
||||
{
|
||||
using var scope = _tenantContext.SetContext(@event.TenantId, "worker");
|
||||
|
||||
// All subsequent operations are scoped to tenant
|
||||
var rules = await _rules.ListAsync(@event.TenantId);
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Handoff Notes
|
||||
|
||||
- Incident storage moved from in-memory to MongoDB with full tenant isolation
|
||||
- Worker should use `ITenantContext.SetContext()` before processing events
|
||||
- All new repositories MUST include tenant filtering in queries
|
||||
- Test tenant isolation with multi-tenant integration tests
|
||||
|
||||
## Related Files
|
||||
|
||||
- `src/Notifier/StellaOps.Notifier.Worker/Tenancy/TenantContext.cs`
|
||||
- `src/Notifier/StellaOps.Notifier.Worker/Tenancy/TenantServiceExtensions.cs`
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Repositories/INotifyIncidentRepository.cs`
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Repositories/NotifyIncidentRepository.cs`
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Serialization/NotifyIncidentDocumentMapper.cs`
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Options/NotifyMongoOptions.cs` (added IncidentsCollection)
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Migrations/EnsureNotifyIndexesMigration.cs` (added incident indexes)
|
||||
- `src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/ServiceCollectionExtensions.cs` (added INotifyIncidentRepository registration)
|
||||
|
||||
Reference in New Issue
Block a user