260322:1648 Correct Coresspondence / Doing RFA / Correct CI
CI Pipeline / build (push) Failing after 12m41s
Build and Deploy / deploy (push) Failing after 2m44s

This commit is contained in:
admin
2026-03-22 16:48:12 +07:00
parent e5deedb42e
commit 11984bfa29
683 changed files with 105251 additions and 29068 deletions
@@ -1,6 +1,7 @@
# 3.11 Document Numbering Management (การจัดการเลขที่เอกสาร)
---
title: 'Functional Requirements: Document Numbering Management'
version: 1.6.0
status: draft
@@ -33,6 +34,7 @@ related:
การนับเลขจะแยกตาม **Counter Key** ที่ประกอบด้วยหลายส่วน ขึ้นกับประเภทเอกสาร
**Scopes**:
1. **Global**: Sequence ระดับระบบทั้งหมด
2. **Organization**: Sequence แยกตามองค์กรผู้ส่ง
3. **Project**: Sequence แยกตามโครงการ
@@ -41,16 +43,16 @@ related:
### Counter Key Components
| Component | Required? | Description | Database Source | Default if NULL |
| ---------------------------- | ---------------- | ------------------- | --------------------------------------------------------- | --------------- |
| `project_id` | ✅ Yes | ID โครงการ | Derived from user context or organization | - |
| `originator_organization_id` | ✅ Yes | ID องค์กรผู้ส่ง | `correspondences.originator_id` | - |
| Component | Required? | Description | Database Source | Default if NULL |
| ---------------------------- | ---------------- | ------------------------ | --------------------------------------------------------- | --------------- |
| `project_id` | ✅ Yes | ID โครงการ | Derived from user context or organization | - |
| `originator_organization_id` | ✅ Yes | ID องค์กรผู้ส่ง | `correspondences.originator_id` | - |
| `recipient_organization_id` | Depends on type | ID องค์กรผู้รับหลัก (TO) | `correspondence_recipients` where `recipient_type = 'TO'` | NULL for RFA |
| `correspondence_type_id` | ✅ Yes | ID ประเภทเอกสาร | `correspondence_types.id` | 0 |
| `sub_type_id` | TRANSMITTAL only | ID ประเภทย่อย | `correspondence_sub_types.id` | 0 |
| `rfa_type_id` | RFA only | ID ประเภท RFA | `rfa_types.id` | 0 |
| `discipline_id` | RFA only | ID สาขางาน | `disciplines.id` | 0 |
| `current_year` | ✅ Yes | ปี ค.ศ. | System year (ปัจจุบัน) | - |
| `correspondence_type_id` | ✅ Yes | ID ประเภทเอกสาร | `correspondence_types.id` | 0 |
| `sub_type_id` | TRANSMITTAL only | ID ประเภทย่อย | `correspondence_sub_types.id` | 0 |
| `rfa_type_id` | RFA only | ID ประเภท RFA | `rfa_types.id` | 0 |
| `discipline_id` | RFA only | ID สาขางาน | `disciplines.id` | 0 |
| `current_year` | ✅ Yes | ปี ค.ศ. | System year (ปัจจุบัน) | - |
### Counter Key แยกตามประเภทเอกสาร (correspondence_type_id)
@@ -61,8 +63,9 @@ related:
```
**หมายเหตุ**:
- ไม่ใช้ `discipline_id`, `sub_type_id`, `rfa_type_id`ทุกประเภทที่ไม่ได้ระบุเฉพาะจะใช้ Template นี้
- ถ้ามีการเพิ่ม - correspondence type ใหม่ใน `correspondence_types` table จะใช้ Template นี้โดยอัตโนมัติ
- ไม่ใช้ `discipline_id`, `sub_type_id`, `rfa_type_id`ทุกประเภทที่ไม่ได้ระบุเฉพาะจะใช้ Template นี้
- ถ้ามีการเพิ่ม - correspondence type ใหม่ใน `correspondence_types` table จะใช้ Template นี้โดยอัตโนมัติ
#### **TRANSMITTAL**:
@@ -71,7 +74,7 @@ related:
correspondence_type_id, sub_type_id, 0, 0, current_year)
```
*หมายเหตุ*: ใช้ `sub_type_id` เพิ่มเติม
_หมายเหตุ_: ใช้ `sub_type_id` เพิ่มเติม
#### **RFA**:
@@ -80,7 +83,7 @@ related:
correspondence_type_id, 0, rfa_type_id, discipline_id, current_year)
```
*หมายเหตุ*: RFA ไม่ใช้ `recipient_organization_id` เพราะเป็นเอกสารโครงการ (CONTRACTOR → CONSULTANT → OWNER)
_หมายเหตุ_: RFA ไม่ใช้ `recipient_organization_id` เพราะเป็นเอกสารโครงการ (CONTRACTOR → CONSULTANT → OWNER)
##### วิธีการหา project_id
@@ -110,6 +113,7 @@ related:
## 3.11.3. Format Templates by Correspondence Type
> **📝 หมายเหตุสำคัญ**
>
> - Templates ด้านล่างเป็น **ตัวอย่าง** สำหรับประเภทเอกสารหลัก
> - ระบบรองรับ **ทุกประเภทเอกสาร** ที่อยู่ใน `correspondence_types` table
> - หากมีการเพิ่มประเภทใหม่ในอนาคต สามารถใช้งานได้โดยอัตโนมัติ
@@ -212,19 +216,19 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
## 3.11.4. Supported Token Types
| Token | Description | Example | Database Source |
| -------------- | ---------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------- |
| `{PROJECT}` | รหัสโครงการ | `LCBP3`, `LCBP3-C2` | `projects.project_code` |
| `{ORIGINATOR}` | รหัสองค์กรผู้ส่ง | `คคง.`, `ผรม.1` | `organizations.organization_code` via `correspondences.originator_id` |
| `{RECIPIENT}` | รหัสองค์กรผู้รับหลัก (TO) | `สคฉ.3`, `กทท.` | `organizations.organization_code` via `correspondence_recipients` where `recipient_type = 'TO'` |
| `{CORR_TYPE}` | รหัสประเภทเอกสาร | `RFA`, `TRANSMITTAL`, `LETTER` | `correspondence_types.type_code` |
| `{SUB_TYPE}` | หมายเลขประเภทย่อย | `11`, `12`, `21` | `correspondence_sub_types.sub_type_number` |
| `{RFA_TYPE}` | รหัสประเภท RFA | `SDW`, `RPT`, `MAT` | `rfa_types.type_code` |
| Token | Description | Example | Database Source |
| -------------- | ------------------------------ | ------------------------------ | ----------------------------------------------------------------------------------------------- |
| `{PROJECT}` | รหัสโครงการ | `LCBP3`, `LCBP3-C2` | `projects.project_code` |
| `{ORIGINATOR}` | รหัสองค์กรผู้ส่ง | `คคง.`, `ผรม.1` | `organizations.organization_code` via `correspondences.originator_id` |
| `{RECIPIENT}` | รหัสองค์กรผู้รับหลัก (TO) | `สคฉ.3`, `กทท.` | `organizations.organization_code` via `correspondence_recipients` where `recipient_type = 'TO'` |
| `{CORR_TYPE}` | รหัสประเภทเอกสาร | `RFA`, `TRANSMITTAL`, `LETTER` | `correspondence_types.type_code` |
| `{SUB_TYPE}` | หมายเลขประเภทย่อย | `11`, `12`, `21` | `correspondence_sub_types.sub_type_number` |
| `{RFA_TYPE}` | รหัสประเภท RFA | `SDW`, `RPT`, `MAT` | `rfa_types.type_code` |
| `{DISCIPLINE}` | รหัสสาขาวิชา | `STR`, `TER`, `GEO` | `disciplines.discipline_code` |
| `{SEQ:n}` | Running number (n = จำนวนหลัก) | `0001`, `0029`, `0985` | Based on `document_number_counters.last_number + 1` |
| `{YEAR:B.E.}` | ปี พ.ศ. | `2568` | `document_number_counters.current_year + 543` |
| `{YEAR:A.D.}` | ปี ค.ศ. | `2025` | `document_number_counters.current_year` |
| `{REV}` | Revision Code | `A`, `B`, `AA` | `correspondence_revisions.revision_label` |
| `{YEAR:B.E.}` | ปี พ.ศ. | `2568` | `document_number_counters.current_year + 543` |
| `{YEAR:A.D.}` | ปี ค.ศ. | `2025` | `document_number_counters.current_year` |
| `{REV}` | Revision Code | `A`, `B`, `AA` | `correspondence_revisions.revision_label` |
### Token Usage Notes
@@ -343,11 +347,13 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
ระบบต้องรองรับการกำหนดเลขที่เอกสารด้วยตนเอง (manual override)
**Use Cases**:
- 1. Import เอกสารเก่าจากระบบเดิม
- 2. External documents จาก client/consultant
- 3. Correction หลังพบความผิดพลาด
**Implementation Details:**
- ตรวจสอบ duplicate ก่อน save
- Validate format ตามรูปแบบที่กำหนด
- Auto-update sequence counter ถ้าเลขที่สูงกว่า current
@@ -360,11 +366,13 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
ระบบต้องรองรับการกำหนดเลขที่เอกสารอัตโนมัติ (auto override)
**Use Cases**:
- 1. Import เอกสารเก่าจากระบบเดิม
- 2. External documents จาก client/consultant
- 3. Correction หลังพบความผิดพลาด
**Implementation Details:**
- ตรวจสอบ duplicate ก่อน save
- Validate format ตามรูปแบบที่กำหนด
- Auto-update sequence counter ถ้าเลขที่สูงกว่า current
@@ -372,6 +380,7 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
- ต้องมีสิทธิ์ Admin ขึ้นไปเท่านั้น
###
## 3.11.9 Audit Trail Requirements
### 3.11.9.1. Audit Logging
@@ -409,18 +418,18 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
**SLA Targets:**
| Metric | Target | Notes |
| ---------------- | -------- | ------------------------ |
| Metric | Target | Notes |
| ---------------- | ---------- | ---------------------------- |
| 95th percentile | ≤ 2 วินาที | ตั้งแต่ request ถึง response |
| 99th percentile | ≤ 5 วินาที | รวม retry attempts |
| Normal operation | ≤ 500ms | ไม่มี retry |
| 99th percentile | ≤ 5 วินาที | รวม retry attempts |
| Normal operation | ≤ 500ms | ไม่มี retry |
### 3.11.10.2. Throughput
**Capacity Targets:**
| Load Level | Target | Notes |
| ----------- | ----------- | --------- |
| Load Level | Target | Notes |
| ----------- | ----------- | ----------- |
| Normal load | ≥ 50 req/s | ใช้งานปกติ |
| Peak load | ≥ 100 req/s | ช่วงเร่งงาน |
@@ -456,8 +465,8 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
ระบบ**ต้อง**alert สำหรับ conditions ต่อไปนี้:
| Severity | Condition | Action |
| ---------- | ---------------------------- | ----------------- |
| Severity | Condition | Action |
| ----------- | ---------------------------- | ----------------- |
| 🔴 Critical | Redis unavailable > 1 minute | PagerDuty + Slack |
| 🔴 Critical | Lock failures > 10% in 5 min | PagerDuty + Slack |
| 🟡 Warning | Lock failures > 5% in 5 min | Slack |
@@ -477,7 +486,6 @@ Drawing Numbering ยังไม่ได้กำหนด Template เนื
**Operations Details:** ดู [Operations Guide - Section 3](file:///e:/np-dms/lcbp3/specs/04-operations/document-numbering-operations.md#3-monitoring--metrics)
## 3.11.12 API Reference
เอกสารนี้อ้างอิงถึง API endpoints ต่อไปนี้:
@@ -567,11 +575,13 @@ Reset counter (Super Admin only, requires approval)
**Primary Table**: `document_number_counters`
**Required Columns:**
- Composite primary key: `(project_id, originator_organization_id, recipient_organization_id, correspondence_type_id, sub_type_id, rfa_type_id, discipline_id, current_year)`
- `version` - สำหรับ optimistic locking
- `last_number` - counter value (เริ่มจาก 0)
**Important Notes:**
- ใช้ `COALESCE(recipient_organization_id, 0)` ใน Primary Key เพื่อรองรับ NULL
- Counter reset ทุกปี (เมื่อ `current_year` เปลี่ยน)
- ต้องมี seed data สำหรับ `correspondence_types`, `rfa_types`, `disciplines` ก่อน
@@ -583,6 +593,7 @@ Reset counter (Super Admin only, requires approval)
**Primary Table**: `document_number_audit`
**Required Columns:**
- `document_id`, `generated_number`, `counter_key` (JSON)
- `template_used`, `user_id`, `ip_address`
- Performance metrics: `retry_count`, `lock_wait_ms`, `total_duration_ms`
@@ -595,6 +606,7 @@ Reset counter (Super Admin only, requires approval)
**Primary Table**: `document_number_errors`
**Required Columns:**
- `error_type` - ENUM classification
- `error_message`, `stack_trace`, `context_data` (JSON)
- `user_id`, `ip_address`, `created_at`, `resolved_at`
@@ -610,6 +622,7 @@ Reset counter (Super Admin only, requires approval)
### 3.11.15.2 Rate Limiting
**Requirements:**
- Limit ต่อ user: **10 requests/minute** (prevent abuse)
- Limit ต่อ IP: **50 requests/minute**
@@ -618,6 +631,7 @@ Reset counter (Super Admin only, requires approval)
### 3.11.15.3 Audit & Compliance
**Requirements:**
- บันทึกทุก API call ที่เกี่ยวข้องกับ document numbering
- เก็บ audit log อย่างน้อย **7 ปี** (ตาม พ.ร.บ. ข้อมูลอิเล็กทรอนิกส์)
- Audit log **ต้องไม่**สามารถแก้ไขได้ (immutable)
@@ -631,7 +645,6 @@ Reset counter (Super Admin only, requires approval)
- [API Design](file:///e:/np-dms/lcbp3/specs/02-architecture/api-design.md)
- [Data Dictionary](file:///e:/np-dms/lcbp3/specs/04-data-dictionary/4_Data_Dictionary_V1_4_4.md)
```
lock:docnum:{project_id}:{org_id}:{recip_id}:{type_id}:{sub}:{rfa}:{disc}:{year}
```
@@ -660,9 +673,11 @@ export class DocumentNumberingLockService {
}
private buildLockKey(key: CounterKey): string {
return `lock:docnum:${key.projectId}:${key.originatorOrgId}:` +
`${key.recipientOrgId ?? 0}:${key.correspondenceTypeId}:` +
`${key.subTypeId}:${key.rfaTypeId}:${key.disciplineId}:${key.year}`;
return (
`lock:docnum:${key.projectId}:${key.originatorOrgId}:` +
`${key.recipientOrgId ?? 0}:${key.correspondenceTypeId}:` +
`${key.subTypeId}:${key.rfaTypeId}:${key.disciplineId}:${key.year}`
);
}
}
```
@@ -717,7 +732,7 @@ export class DocumentNumberCounter {
// ใช้ TypeORM Transaction + Optimistic Lock
await this.connection.transaction(async (manager) => {
const counter = await manager.findOne(DocumentNumberCounter, {
where: counterKey
where: counterKey,
});
counter.lastNumber += 1;
@@ -951,8 +966,16 @@ import { Injectable } from '@nestjs/common';
@Injectable()
export class TemplateValidator {
private readonly ALLOWED_TOKENS = [
'PROJECT', 'ORIGINATOR', 'RECIPIENT', 'CORR_TYPE',
'SUB_TYPE', 'RFA_TYPE', 'DISCIPLINE', 'SEQ', 'YEAR', 'REV'
'PROJECT',
'ORIGINATOR',
'RECIPIENT',
'CORR_TYPE',
'SUB_TYPE',
'RFA_TYPE',
'DISCIPLINE',
'SEQ',
'YEAR',
'REV',
];
validate(template: string, correspondenceType: string): ValidationResult {
@@ -968,13 +991,13 @@ export class TemplateValidator {
// กฎพิเศษสำหรับแต่ละประเภท
if (correspondenceType === 'RFA') {
if (!tokens.some(t => t.name === 'PROJECT')) {
if (!tokens.some((t) => t.name === 'PROJECT')) {
errors.push('RFA template ต้องมี {PROJECT}');
}
}
if (correspondenceType === 'TRANSMITTAL') {
if (!tokens.some(t => t.name === 'SUB_TYPE')) {
if (!tokens.some((t) => t.name === 'SUB_TYPE')) {
errors.push('TRANSMITTAL template ต้องมี {SUB_TYPE}');
}
}
@@ -1045,14 +1068,14 @@ export class ConfigHistoryService {
templateBefore: oldTemplate,
templateAfter: newTemplate,
changedBy: userId,
changeReason: reason
changeReason: reason,
});
}
async rollback(configId: number, historyId: number): Promise<void> {
const history = await this.historyRepo.findOne({ where: { id: historyId }});
const history = await this.historyRepo.findOne({ where: { id: historyId } });
await this.configService.update(configId, {
template: history.templateBefore
template: history.templateBefore,
});
}
}
@@ -1108,6 +1131,7 @@ async resetCounter(
await this.counterService.reset(configId);
}
```
## 3.11.21 Audit Trail
### 3.11.21.1 การบันทึก Audit Log
@@ -1161,7 +1185,7 @@ export class DocumentNumberAuditService {
retryCount: data.retryCount ?? 0,
lockWaitMs: data.lockWaitMs,
totalDurationMs: data.totalDurationMs,
fallbackUsed: data.fallbackUsed ?? 'NONE'
fallbackUsed: data.fallbackUsed ?? 'NONE',
});
}
}
@@ -1194,7 +1218,7 @@ export class DocumentNumberingService {
retryCount,
lockWaitMs,
totalDurationMs: Date.now() - startTime,
fallbackUsed
fallbackUsed,
});
return number;
@@ -1249,7 +1273,7 @@ export class ErrorLogService {
stackTrace: error.stack,
contextData: JSON.stringify(context),
userId: context.userId,
ipAddress: context.ipAddress
ipAddress: context.ipAddress,
});
// Alert if critical
@@ -1257,7 +1281,7 @@ export class ErrorLogService {
await this.alertService.sendAlert({
severity: 'CRITICAL',
title: `Document Numbering Error: ${errorType}`,
details: error.message
details: error.message,
});
}
}
@@ -1271,11 +1295,13 @@ export class ErrorLogService {
}
}
```
## 3.11.22 Performance Requirements
### 3.11.22.1 Response Time
**Target Response Times**:
- **95th percentile**: ≤ 2 วินาที
- **99th percentile**: ≤ 5 วินาที
- **Normal operation** (ไม่มี retry): ≤ 500ms
@@ -1327,7 +1353,7 @@ const generationDuration = new Histogram({
name: 'docnum_generation_duration_seconds',
help: 'Document number generation duration',
labelNames: ['project', 'type', 'status'],
buckets: [0.1, 0.5, 1, 2, 5, 10]
buckets: [0.1, 0.5, 1, 2, 5, 10],
});
// Usage
@@ -1357,7 +1383,7 @@ services:
backend:
image: lcbp3-backend:latest
deploy:
replicas: 3 # 3 instances
replicas: 3 # 3 instances
resources:
limits:
cpus: '1.0'
@@ -1371,7 +1397,7 @@ services:
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
- '80:80'
```
```nginx
@@ -1402,7 +1428,7 @@ import { ThrottlerGuard } from '@nestjs/throttler';
@Controller('document-numbering')
@UseGuards(ThrottlerGuard)
export class DocumentNumberingController {
@Throttle(10, 60) // 10 requests per 60 seconds per user
@Throttle(10, 60) // 10 requests per 60 seconds per user
@Post('generate')
async generate(@Body() dto: GenerateNumberDto) {
return await this.service.generate(dto);
@@ -1466,17 +1492,18 @@ export class HealthController {
return this.health.check([
() => this.db.pingCheck('database'),
() => this.redis.pingCheck('redis'),
() => this.customHealthCheck()
() => this.customHealthCheck(),
]);
}
private async customHealthCheck() {
// ทดสอบ generate document number
const canGenerate = await this.testGeneration();
return { documentNumbering: { status: canGenerate ? 'up' : 'down' }};
return { documentNumbering: { status: canGenerate ? 'up' : 'down' } };
}
}
```
## 3.11.23 Monitoring & Alerting
### 3.11.23.1 Metrics Collection
@@ -1495,13 +1522,13 @@ export class DocumentNumberingMetrics {
name: 'docnum_lock_acquisition_duration_ms',
help: 'Lock acquisition time in milliseconds',
labelNames: ['project', 'type'],
buckets: [10, 50, 100, 200, 500, 1000, 2000, 5000]
buckets: [10, 50, 100, 200, 500, 1000, 2000, 5000],
});
private lockAcquisitionFailures = new Counter({
name: 'docnum_lock_acquisition_failures_total',
help: 'Total number of lock acquisition failures',
labelNames: ['project', 'type', 'reason']
labelNames: ['project', 'type', 'reason'],
});
// Generation metrics
@@ -1509,25 +1536,25 @@ export class DocumentNumberingMetrics {
name: 'docnum_generation_duration_ms',
help: 'Total document number generation time',
labelNames: ['project', 'type', 'status'],
buckets: [100, 200, 500, 1000, 2000, 5000]
buckets: [100, 200, 500, 1000, 2000, 5000],
});
private retryCount = new Histogram({
name: 'docnum_retry_count',
help: 'Number of retries per generation',
labelNames: ['project', 'type'],
buckets: [0, 1, 2, 3, 5, 10]
buckets: [0, 1, 2, 3, 5, 10],
});
// Connection health
private redisConnectionStatus = new Gauge({
name: 'docnum_redis_connection_status',
help: 'Redis connection status (1=up, 0=down)'
help: 'Redis connection status (1=up, 0=down)',
});
private dbConnectionPoolUsage = new Gauge({
name: 'docnum_db_connection_pool_usage',
help: 'Database connection pool usage percentage'
help: 'Database connection pool usage percentage',
});
}
```
@@ -1549,8 +1576,8 @@ groups:
severity: critical
component: document-numbering
annotations:
summary: "Redis is unavailable for document numbering"
description: "System is falling back to DB-only locking"
summary: 'Redis is unavailable for document numbering'
description: 'System is falling back to DB-only locking'
# CRITICAL: High lock failure rate
- alert: HighLockFailureRate
@@ -1560,8 +1587,8 @@ groups:
labels:
severity: critical
annotations:
summary: "Lock acquisition failure rate > 10%"
description: "Check Redis and database performance"
summary: 'Lock acquisition failure rate > 10%'
description: 'Check Redis and database performance'
# WARNING: Elevated lock failure rate
- alert: ElevatedLockFailureRate
@@ -1571,7 +1598,7 @@ groups:
labels:
severity: warning
annotations:
summary: "Lock acquisition failure rate > 5%"
summary: 'Lock acquisition failure rate > 5%'
# WARNING: Slow lock acquisition
- alert: SlowLockAcquisition
@@ -1583,7 +1610,7 @@ groups:
labels:
severity: warning
annotations:
summary: "P95 lock acquisition time > 1 second"
summary: 'P95 lock acquisition time > 1 second'
# WARNING: High retry count
- alert: HighRetryCount
@@ -1595,7 +1622,7 @@ groups:
labels:
severity: warning
annotations:
summary: "Retry count > 100 per hour in project {{ $labels.project }}"
summary: 'Retry count > 100 per hour in project {{ $labels.project }}'
# WARNING: Slow generation
- alert: SlowDocumentNumberGeneration
@@ -1607,7 +1634,7 @@ groups:
labels:
severity: warning
annotations:
summary: "P95 generation time > 2 seconds"
summary: 'P95 generation time > 2 seconds'
```
**AlertManager Configuration** (`alertmanager/config.yml`):
@@ -1659,9 +1686,11 @@ receivers:
"panels": [
{
"title": "Lock Acquisition Success Rate",
"targets": [{
"expr": "1 - (rate(docnum_lock_acquisition_failures_total[5m]) / rate(docnum_lock_acquisition_total[5m]))"
}],
"targets": [
{
"expr": "1 - (rate(docnum_lock_acquisition_failures_total[5m]) / rate(docnum_lock_acquisition_total[5m]))"
}
],
"type": "graph",
"gridPos": { "x": 0, "y": 0, "w": 12, "h": 8 }
},
@@ -1686,17 +1715,21 @@ receivers:
},
{
"title": "Generation Rate (per minute)",
"targets": [{
"expr": "sum(rate(docnum_generation_duration_ms_count[1m])) * 60"
}],
"targets": [
{
"expr": "sum(rate(docnum_generation_duration_ms_count[1m])) * 60"
}
],
"type": "stat",
"gridPos": { "x": 0, "y": 8, "w": 6, "h": 4 }
},
{
"title": "Redis Connection Status",
"targets": [{
"expr": "docnum_redis_connection_status"
}],
"targets": [
{
"expr": "docnum_redis_connection_status"
}
],
"type": "stat",
"gridPos": { "x": 6, "y": 8, "w": 6, "h": 4 },
"thresholds": {
@@ -1709,9 +1742,11 @@ receivers:
},
{
"title": "Error Rate by Type",
"targets": [{
"expr": "sum by (reason) (rate(docnum_lock_acquisition_failures_total[5m]))"
}],
"targets": [
{
"expr": "sum by (reason) (rate(docnum_lock_acquisition_failures_total[5m]))"
}
],
"type": "graph",
"gridPos": { "x": 12, "y": 8, "w": 12, "h": 8 }
}