> For the complete documentation index, see [llms.txt](https://kythuat.dtechvn.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kythuat.dtechvn.com/cai-dat-dtech/quan-ly-tram.md).

# QUẢN LÝ TRẠM

## KIỂM TRA TRẠM, USER ĐANG NHẬP

Nhìn vào thời gian nào đăng nhập xa nhất, thì có thể là trạm đó không sử dụng. Báo lại khách hàng kiểm tra user đó còn hoạt động hay không để xử lý tiếp

```sql
  with cte_lichsu as (
  select ComputerName as tenmaytinh, CreateDate as ngayTao,tram, [user] as userDangnhap
  , ROW_NUMBER() over(partition by tram order by createdate desc) as stt
  From chamcong
  where CreateDate>='01/01/2025' --- chặn thời gian cho phù hợp.
  )
  select cte_lichsu.*, users.ten 
  from cte_lichsu 
  inner join [users]  on cte_lichsu.userDangnhap=[users].[user]
  where cte_lichsu.stt=1
  order by tram
------------------ code dưới không sử dụng. vì không chuẩn------
-- Liệt kê các trạm đăng nhập
select T1.*, T2.ten
from
(
    select max(computername) as tenmaytinh,max(noidung) as noidung,
        max(createdate) as thoigian,
        max([user]) as nguoidung,
        tram 
    From chamcong 
	--WHERE NOIDUNG LIKE N'%thuỷ%' -- where thêm ở nội dung sẽ chuẩn hơn
    Group by tram
)T1 
inner join 
(select [user] as nguoidung,* from [users])T2 
on T1.nguoidung = T2.nguoidung
Order by thoigian des
```

## TRẠM ĐĂNG NHẬP BẢN DỊCH VỤ

1. Danh sách tất cả các database và trạm thỏa mãn điều kiện

```sql
DECLARE @DBName NVARCHAR(128);
DECLARE @SQL NVARCHAR(MAX) = N'';
DECLARE @CheckSQL NVARCHAR(MAX);
DECLARE @IsTargetDB INT;

-- 1. Quét các Database đang Online và không phải DB hệ thống
DECLARE db_cursor CURSOR LOCAL FAST_FORWARD FOR
SELECT name
FROM sys.databases
WHERE database_id > 4 AND state = 0;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @DBName;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @IsTargetDB = 0;

    -- 2. KIỂM TRA CẤU TRÚC VÀ ĐIỀU KIỆN THÔNG TƯ ĐẦU VÀO
    -- Lớp 1: Kiểm tra sự tồn tại của bảng và cột để tránh lỗi biên dịch (Compile Error)
    -- Lớp 2: Kiểm tra xem ThongTuApp có thuộc danh sách '88' hoặc '152' không
    SET @CheckSQL = N'
        SET @Result = 0;
        
        IF OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') IS NOT NULL
           AND EXISTS (SELECT 1 FROM [' + @DBName + N'].sys.columns WHERE object_id = OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') AND name = ''ThongTuApp'')
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.chamcong'') IS NOT NULL
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.users'') IS NOT NULL
        BEGIN
            -- Thực thi SQL động cấp 2: Dùng IN để lọc cùng lúc nhiều thông tư
            DECLARE @InnerSQL NVARCHAR(MAX) = N''IF EXISTS (SELECT 1 FROM [' + @DBName + N'].dbo.CustomsInfor WHERE ThongTuApp IN (''''88'''', ''''152'''')) SET @Match = 1;'';
            EXEC sp_executesql @InnerSQL, N''@Match INT OUTPUT'', @Match = @Result OUTPUT;
        END';

    -- Thực thi lệnh kiểm tra và gán kết quả vào @IsTargetDB
    EXEC sp_executesql @CheckSQL, N'@Result INT OUTPUT', @Result = @IsTargetDB OUTPUT;

    -- 3. NẾU DATABASE NÀY HỢP LỆ (Thỏa mãn 1 trong 2 thông tư) -> Tiến hành nối chuỗi UNION ALL
    IF @IsTargetDB = 1
    BEGIN
        SET @SQL = @SQL +
            N'SELECT ''' + @DBName + N''' AS TenDatabase, ' +
            -- Thêm cột hiển thị thông tư thực tế của database để bạn dễ quản lý, theo dõi
            N'       (SELECT TOP 1 ThongTuApp FROM [' + @DBName + N'].dbo.CustomsInfor) AS ThongTuApDung, ' +
            N'       c.tenmaytinh, c.ngayTao, c.tram, c.userDangnhap, u.ten ' +
            N'FROM ( ' +
            N'    SELECT ComputerName AS tenmaytinh, CreateDate AS ngayTao, tram, [user] AS userDangnhap, ' +
            N'           ROW_NUMBER() OVER(PARTITION BY tram ORDER BY CreateDate DESC) AS stt ' +
            N'    FROM [' + @DBName + N'].dbo.chamcong ' +
            N'    WHERE CreateDate >= ''20250101'' ' + 
            N') c ' +
            N'INNER JOIN [' + @DBName + N'].dbo.[users] u ON c.userDangnhap = u.[user] ' +
            N'WHERE c.stt = 1 ' +
            N'UNION ALL ' + CHAR(13) + CHAR(10);
    END

    FETCH NEXT FROM db_cursor INTO @DBName;
END

CLOSE db_cursor;
DEALLOCATE db_cursor;

-- 4. Chạy câu lệnh tổng hợp
IF LEN(@SQL) > 0
BEGIN
    -- Cắt bỏ chữ 'UNION ALL ' và ký tự xuống dòng ở cuối chuỗi
    SET @SQL = LEFT(@SQL, LEN(@SQL) - 12); 
    
    -- Sắp xếp theo Tên Database, Thông tư áp dụng và Tên trạm
    SET @SQL = @SQL + N' ORDER BY TenDatabase, ThongTuApDung, tram;';

    -- Bạn có thể mở comment dòng PRINT dưới đây để kiểm tra cấu trúc câu lệnh hoàn chỉnh trước khi thực thi
    -- PRINT CAST(@SQL AS NTEXT); 
    
    EXEC sp_executesql @SQL;
END
ELSE
BEGIN
    PRINT N'Không tìm thấy cơ sở dữ liệu nào áp dụng Thông tư 88 hoặc 152.';
END
```

2. Danh sách các trạm thỏa mãn điều kiện:

```sql
DECLARE @DBName NVARCHAR(128);
DECLARE @SQL NVARCHAR(MAX) = N'';
DECLARE @CheckSQL NVARCHAR(MAX);
DECLARE @IsTargetDB INT;

-- 1. Quét các Database
DECLARE db_cursor CURSOR LOCAL FAST_FORWARD FOR
SELECT name
FROM sys.databases
WHERE database_id > 4 AND state = 0;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @DBName;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @IsTargetDB = 0;

    -- 2. Kiểm tra điều kiện Database (Chứa bảng/cột và ThongTuApp = 88 hoặc 152)
    SET @CheckSQL = N'
        SET @Result = 0;
        
        IF OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') IS NOT NULL
           AND EXISTS (SELECT 1 FROM [' + @DBName + N'].sys.columns WHERE object_id = OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') AND name = ''ThongTuApp'')
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.chamcong'') IS NOT NULL
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.users'') IS NOT NULL
        BEGIN
            DECLARE @InnerSQL NVARCHAR(MAX) = N''IF EXISTS (SELECT 1 FROM [' + @DBName + N'].dbo.CustomsInfor WHERE ThongTuApp IN (''''88'''', ''''152'''')) SET @Match = 1;'';
            EXEC sp_executesql @InnerSQL, N''@Match INT OUTPUT'', @Match = @Result OUTPUT;
        END';

    EXEC sp_executesql @CheckSQL, N'@Result INT OUTPUT', @Result = @IsTargetDB OUTPUT;

    -- 3. Ghép chuỗi truy vấn: Đã bỏ các cột Tên Database và Thông tư
    IF @IsTargetDB = 1
    BEGIN
        SET @SQL = @SQL +
            N'SELECT c.tenmaytinh, c.ngayTao, c.tram, c.userDangnhap, u.ten ' +
            N'FROM ( ' +
            N'    SELECT ComputerName AS tenmaytinh, CreateDate AS ngayTao, tram, [user] AS userDangnhap, ' +
            N'           ROW_NUMBER() OVER(PARTITION BY tram ORDER BY CreateDate DESC) AS stt ' +
            N'    FROM [' + @DBName + N'].dbo.chamcong ' +
            N'    WHERE CreateDate >= ''20250101'' ' + 
            N') c ' +
            N'INNER JOIN [' + @DBName + N'].dbo.[users] u ON c.userDangnhap = u.[user] ' +
            N'WHERE c.stt = 1 ' +
            N'UNION ALL ' + CHAR(13) + CHAR(10);
    END

    FETCH NEXT FROM db_cursor INTO @DBName;
END

CLOSE db_cursor;
DEALLOCATE db_cursor;

-- 4. Bọc toàn bộ chuỗi SQL vào một CTE lớn và lọc lại lần cuối trên toàn hệ thống
IF LEN(@SQL) > 0
BEGIN
    -- Cắt bỏ chữ 'UNION ALL ' ở cuối chuỗi
    SET @SQL = LEFT(@SQL, LEN(@SQL) - 12); 
    
    -- Khởi tạo câu lệnh Final bằng cách bọc @SQL vào bên trong
    DECLARE @FinalSQL NVARCHAR(MAX) = N'
WITH AllDB_Data AS (
    ' + @SQL + N'
),
Global_Rank AS (
    SELECT tenmaytinh, ngayTao, tram, userDangnhap, ten,
           ROW_NUMBER() OVER(PARTITION BY tram ORDER BY ngayTao DESC) AS global_stt
    FROM AllDB_Data
)
SELECT tenmaytinh, ngayTao, tram, userDangnhap, ten
FROM Global_Rank
WHERE global_stt = 1
ORDER BY tram,ngayTao DESC;'; -- Ưu tiên hiển thị các đăng nhập mới nhất lên trên cùng

    -- PRINT CAST(@FinalSQL AS NTEXT); -- Kiểm tra chuỗi sinh ra nếu cần
    EXEC sp_executesql @FinalSQL;
END
ELSE
BEGIN
    PRINT N'Không tìm thấy cơ sở dữ liệu nào áp dụng Thông tư 88 hoặc 152.';
END
```

3. Tìm kiếm tên máy tính hoặc số trạm xuất hiện trên những database nào

```sql
-- =====================================================================
-- 0. CẤU HÌNH TÌM KIẾM (TÙY CHỈNH TẠI ĐÂY)
-- =====================================================================
-- Nhập tên máy tính hoặc số trạm cần tìm. 
-- Ví dụ: N'TRAM-01' hoặc N'PC-KETOAN'. 
-- Để chuỗi rỗng N'' nếu muốn lấy lên toàn bộ danh sách.
--DECLARE @SearchKeyword NVARCHAR(100) = N'ADMIN01'; --Tìm tên máy tính
DECLARE @SearchKeyword NVARCHAR(100) = N'11';  --- Tìm theo số trạm

-- =====================================================================

DECLARE @DBName NVARCHAR(128);
DECLARE @SQL NVARCHAR(MAX) = N'';
DECLARE @CheckSQL NVARCHAR(MAX);
DECLARE @IsTargetDB INT;

-- 1. Quét các Database đang Online và không phải DB hệ thống
DECLARE db_cursor CURSOR LOCAL FAST_FORWARD FOR
SELECT name
FROM sys.databases
WHERE database_id > 4 AND state = 0;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @DBName;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @IsTargetDB = 0;

    -- 2. KIỂM TRA CẤU TRÚC VÀ ĐIỀU KIỆN THÔNG TƯ ĐẦU VÀO
    SET @CheckSQL = N'
        SET @Result = 0;
        
        IF OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') IS NOT NULL
           AND EXISTS (SELECT 1 FROM [' + @DBName + N'].sys.columns WHERE object_id = OBJECT_ID(N''[' + @DBName + N'].dbo.CustomsInfor'') AND name = ''ThongTuApp'')
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.chamcong'') IS NOT NULL
           AND OBJECT_ID(N''[' + @DBName + N'].dbo.users'') IS NOT NULL
        BEGIN
            -- Lọc các database đang áp dụng TT 88 hoặc 152
            DECLARE @InnerSQL NVARCHAR(MAX) = N''IF EXISTS (SELECT 1 FROM [' + @DBName + N'].dbo.CustomsInfor WHERE ThongTuApp IN (''''133'''', ''''200'''', ''''99'''')) SET @Match = 1;'';
            EXEC sp_executesql @InnerSQL, N''@Match INT OUTPUT'', @Match = @Result OUTPUT;
        END';

    EXEC sp_executesql @CheckSQL, N'@Result INT OUTPUT', @Result = @IsTargetDB OUTPUT;

    -- 3. GHI NHẬN DATABASE HỢP LỆ VÀ NỐI CHUỖI
    IF @IsTargetDB = 1
    BEGIN
        SET @SQL = @SQL +
            N'SELECT ''' + @DBName + N''' AS TenDatabase, ' +
            N'       (SELECT TOP 1 ThongTuApp FROM [' + @DBName + N'].dbo.CustomsInfor) AS ThongTuApDung, ' +
            N'       c.tenmaytinh, c.ngayTao, c.tram, c.userDangnhap, u.ten ' +
            N'FROM ( ' +
            N'    SELECT ComputerName AS tenmaytinh, CreateDate AS ngayTao, tram, [user] AS userDangnhap, ' +
            N'           ROW_NUMBER() OVER(PARTITION BY tram ORDER BY CreateDate DESC) AS stt ' +
            N'    FROM [' + @DBName + N'].dbo.chamcong ' +
            N'    WHERE CreateDate >= ''20200101'' ' + 
            N') c ' +
            N'INNER JOIN [' + @DBName + N'].dbo.[users] u ON c.userDangnhap = u.[user] ' +
            N'WHERE c.stt = 1 ' +
            -- Áp dụng bộ lọc tìm kiếm tương đối (LIKE) đối với tên máy tính HOẶC tên trạm
            N'  AND (@SearchKeyword = N'''' ' + 
            N'       OR c.tenmaytinh LIKE N''%'' + @SearchKeyword + N''%'' ' + 
            N'       OR c.tram LIKE N''%'' + @SearchKeyword + N''%'') ' +
            N'UNION ALL ' + CHAR(13) + CHAR(10);
    END

    FETCH NEXT FROM db_cursor INTO @DBName;
END

CLOSE db_cursor;
DEALLOCATE db_cursor;

-- 4. THỰC THI TRUY VẤN
IF LEN(@SQL) > 0
BEGIN
    -- Cắt bỏ chữ 'UNION ALL ' ở cuối chuỗi
    SET @SQL = LEFT(@SQL, LEN(@SQL) - 12); 
    
    -- Sắp xếp theo Tên Database, thời gian đăng nhập mới nhất và Tên trạm
    SET @SQL = @SQL + N' ORDER BY TenDatabase, c.ngayTao DESC, tram;';

    -- Thực thi SQL Động và truyền biến @SearchKeyword vào ngữ cảnh thực thi
    EXEC sp_executesql @SQL, 
                       N'@SearchKeyword NVARCHAR(100)', 
                       @SearchKeyword = @SearchKeyword;
END
ELSE
BEGIN
    PRINT N'Không tìm thấy cơ sở dữ liệu nào áp dụng Thông tư 133 hoặc 200,99.';
END
```

## RESET ID TRẠM BẢN DEV Cũ

```sql
--ÁP DỤNG CHO BẢN DEV CŨ KHÔNG CÓ RESET NHIỀU DATABASE
-- CHÚ Ý CHỈ ÁP DỤNG CHO MÁY CHỈ CÓ RIÊNG BẢN KẾ TOÁN DEV CŨ, 
--Nếu có cả DEV mới và 88 thì không dùng được

--1. Kiểm tra danh sách các database
SELECT name,database_id FROM sys.databases
WHERE database_id>6 -- Lấy ra Vị trí của database bắt đầu dùng DTECH, lại đi các db của hệ thống (master, model,msdb,tempdb,report...)

--2. Dựa theo vị trí để điền lại vào @id_data

DECLARE @vitri int -- Vị trí những mã trống theo thứ tự tăng dần
DECLARE @tendb NVARCHAR(300)
DECLARE @id_tram INT
DECLARE @id_data INT
DECLARE @sql_cmm NVARCHAR(MAX)
Declare @err_state int =0;  -- Trạng thái lỗi trả về

SET @id_tram =1  -- ID trạm cần reset
SET @id_data = 7  -- Vị trí id của database bắt đầu dùng DTECH

--Tạo 1 bảng tạm quét danh sách các database
declare bangdsdata cursor for
select ROW_NUMBER() OVER(ORDER BY name ASC) AS vitri,name from sys.databases where database_id>=@id_data
open bangdsdata 
Fetch next from bangdsdata
	into @vitri,@tendb
While @@FETCH_STATUS=0
BEGIN
	print '--vitri: '+ CONVERT(NVARCHAR,@vitri)
	--print 'Ma: '+@kytu+FORMAT(@maxso+@vitri,'00000')
	--PRINT 'Update: '+'Update ['+@tendb+'].dbo.Tram set trangthai=0,modidate=getdate() where tram='+CONVERT(NVARCHAR,@id_tram)
	SET @sql_cmm='Update ['+@tendb+'].dbo.Tram set trangthai=0,modidate=getdate() where tram='+CONVERT(NVARCHAR,@id_tram)
	BEGIN TRY
		PRINT @sql_cmm
		EXEC(@sql_cmm)
	END TRY
	BEGIN CATCH
		SELECT @err_state = ERROR_STATE()
	END CATCH;
	Fetch next from bangdsdata
	into @vitri,@tendb
END
CLOSE bangdsdata
DEALLOCATE bangdsdata


```

TRƯỜNG HỢP CÓ CẢ DATABASE BẢN DEV CŨ VÀ DEV MỚI thì cần lọc theo tên thư mục cài đặt để reset

```sql
--0. Kiểm tra danh sách các database

SELECT T1.name,T1.database_id,T2.physical_name
FROM sys.databases T1
join sys.master_files T2
on T1.database_id = T2.database_id
WHERE T2.type_desc = 'ROWS'
and Charindex(N'\DtechService\',T2.physical_name)>0
---------------------------------------------------------
--1. Khai báo các tham số
DECLARE @vitri INT -- Vị trí thứ tự tăng dần
DECLARE @tendb NVARCHAR(300)
DECLARE @id_tram INT
DECLARE @sql_cmm NVARCHAR(MAX)
DECLARE @err_state INT = 0; -- Trạng thái lỗi trả về

SET @id_tram = 4 -- ID trạm cần reset

-- 2. Sửa Cursor để duyệt qua danh sách database thỏa mãn điều kiện đường dẫn vật lý
DECLARE bangdsdata CURSOR FOR
SELECT 
    ROW_NUMBER() OVER(ORDER BY T1.name ASC) AS vitri,
    T1.name 
FROM sys.databases T1
JOIN sys.master_files T2 ON T1.database_id = T2.database_id
WHERE T2.type_desc = 'ROWS' -- Chỉ lấy file dữ liệu, tránh lấy file LOG
AND CHARINDEX(N'\DtechService\', T2.physical_name) > 0

OPEN bangdsdata
FETCH NEXT FROM bangdsdata INTO @vitri, @tendb

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT N'-- Đang xử lý vị trí: ' + CONVERT(NVARCHAR, @vitri) + ' | Database: ' + @tendb
    
    -- Xây dựng câu lệnh Update động
    SET @sql_cmm = 'UPDATE [' + @tendb + '].dbo.Tram SET trangthai = 0, modidate = GETDATE() WHERE tram = ' + CONVERT(NVARCHAR, @id_tram)
    
    BEGIN TRY
        PRINT N'Lệnh thực thi: ' + @sql_cmm
        --EXEC(@sql_cmm)
    END TRY
    BEGIN CATCH
        PRINT N'Lỗi tại Database: ' + @tendb
        SELECT @err_state = ERROR_STATE()
    END CATCH;

    FETCH NEXT FROM bangdsdata INTO @vitri, @tendb
END

CLOSE bangdsdata
DEALLOCATE bangdsdata

```

## CẬP NHẬT ĐƯỜNG DẪN BACKUP TẤT CẢ CÁC DATABASE BẢN DỊCH VỤ

```sql
--ÁP DỤNG CHO BẢN DEV CŨ KHÔNG CÓ RESET NHIỀU DATABASE
-- CHÚ Ý CHỈ ÁP DỤNG CHO MÁY CHỈ CÓ RIÊNG BẢN KẾ TOÁN DEV CŨ, 

--1. Kiểm tra danh sách các database
SELECT name,database_id FROM sys.databases
WHERE database_id>4 -- Lấy ra Vị trí của database bắt đầu dùng DTECH, lại đi các db của hệ thống (master, model,msdb,tempdb,report...)

--2. Dựa theo vị trí để điền lại vào @id_data

DECLARE @vitri int -- Vị trí những mã trống theo thứ tự tăng dần
DECLARE @tendb NVARCHAR(300)
DECLARE @id_tram INT
DECLARE @id_data INT
DECLARE @sql_cmm NVARCHAR(MAX)
Declare @err_state int =0;  -- Trạng thái lỗi trả về
DECLARE @path NVARCHAR(MAX)
DECLARE @value NVARCHAR(MAX)

SET @path=N'E:\DTECH\DtechService\Backup'  -- Đường dẫn backup SQL
SET @value =N'SelectedPath'

--SET @id_tram =1  -- ID trạm cần reset
SET @id_data = 5  -- Vị trí id của database bắt đầu dùng DTECH

--Tạo 1 bảng tạm quét danh sách các database
declare bangdsdata cursor for
select ROW_NUMBER() OVER(ORDER BY name ASC) AS vitri,name from sys.databases where database_id>=@id_data
open bangdsdata 
Fetch next from bangdsdata
	into @vitri,@tendb
While @@FETCH_STATUS=0
BEGIN
	print '--vitri: '+ CONVERT(NVARCHAR,@vitri)
	--print 'Ma: '+@kytu+FORMAT(@maxso+@vitri,'00000')
	--PRINT 'Update: '+'Update ['+@tendb+'].dbo.Tram set trangthai=0,modidate=getdate() where tram='+CONVERT(NVARCHAR,@id_tram)
	--SET @sql_cmm='Update ['+@tendb+'].dbo.Tram set trangthai=0,modidate=getdate() where tram='+CONVERT(NVARCHAR,@id_tram)
	SET @sql_cmm='Update ['+@tendb+'].dbo.Dregistry set value='''+@path+''' where name='''+@value+''''
	BEGIN TRY
		PRINT @sql_cmm
		EXEC(@sql_cmm)
	END TRY
	BEGIN CATCH
		SELECT @err_state = ERROR_STATE()
	END CATCH;
	Fetch next from bangdsdata
	into @vitri,@tendb
END
CLOSE bangdsdata
DEALLOCATE bangdsdata


```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kythuat.dtechvn.com/cai-dat-dtech/quan-ly-tram.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
