Requirements
Concept & System DesignTrình bày ý tưởng KMS Technical RequirementsNestJS · Next.js · MongoDB
Technical Requirement Spec

Company KMS — Requirements

Danh sách các yêu cầu chức năng và kỹ thuật để xây dựng hệ thống, trình bày dạng gạch đầu dòng theo từng nhóm. Toàn bộ bám theo stack NestJS · Next.js · MongoDB. Mỗi mục được đánh dấu mức độ ưu tiên theo chú thích bên dưới.

NestJS · REST API Next.js · App Router MongoDB · Mongoose Redis · Cache/Queue Azure Blob · Files
= MUST have (bắt buộc MVP) + = Enhancement (mở rộng, nên có)

01 Kiến trúc & Tech Stack

Next.js (Frontend) App Router · SSR/ISRMarkdown editor HTML viewer (sandboxed)Auth session (cookie) NestJS (API) Auth · Guards · CASLModules: Space/Article/… Workflow state machineBullMQ workers (jobs) Validation · Sanitize MongoDBdocuments · versions Rediscache · queue · sessions Azure Blobattachments · html · pdf Azure AI Searchvector + full-text EXTERNAL SSO / OAuth2 (Google Workspace)SMTP / Email · Azure Blob Storage Search: Azure AI Search HTTPS/JSON
Next.js (BFF/SSR) → NestJS REST API → MongoDB + Redis + Azure Blob Storage; Azure AI Search (full-text + vector) thêm ở giai đoạn sau.
  • Backend: NestJS (modular, mỗi domain 1 module), Mongoose ODM, class-validator + class-transformer cho DTO.
  • Frontend: Next.js App Router; SSR cho trang đọc tài liệu (SEO nội bộ + tốc độ), CSR cho editor.
  • Database: MongoDB — Azure Cosmos DB for MongoDB (managed) hoặc self-host + replica set để bật transaction.
  • Redis: cache, rate-limit, session store, và hàng đợi job (BullMQ) cho email/notification/re-index.
  • Object storage: Azure Blob Storage cho file upload (KHÔNG lưu binary trong Mongo — chỉ lưu metadata + blob URL/key).
  • API contract: OpenAPI/Swagger tự sinh từ NestJS decorators; versioning qua /api/v1.

02 Authentication

  • Đăng ký/đăng nhập bằng email + password; hash mật khẩu bằng argon2 (hoặc bcrypt cost ≥ 12).
  • JWT access token (ngắn hạn ~15 phút) + refresh token (dài hạn, xoay vòng / rotation).
  • Refresh token lưu httpOnly + Secure + SameSite cookie; access token gửi qua header Authorization: Bearer.
  • Thu hồi token: lưu danh sách refresh token hợp lệ trong Redis; logout = xoá; đổi mật khẩu = revoke toàn bộ.
  • SSO / OAuth2 với Google Workspace — passport-google-oauth20; map domain email → auto-provision user.
  • 2FA/MFA tuỳ chọn (TOTP, otplib) cho tài khoản Admin/Super Admin.
  • Quên mật khẩu qua email token có hạn; xác minh email khi đăng ký.
  • Session management: user xem & thu hồi các phiên đăng nhập (thiết bị, IP, thời gian).
  • Account status: active / invited / suspended / disabled — nghỉ việc thì disable, giữ nguyên tài liệu.
Chống thất thoát tri thức: khi nhân sự nghỉ, không xoá user mà chuyển disabledreassign owner tài liệu Official sang Lead/Space Owner — tài liệu chính thức không bao giờ mồ côi.

03 Authorization / RBAC

3 tầng phân quyền độc lập, kết hợp lại khi kiểm tra 1 request.

1 · System Role Super AdminAdminUserphạm vi: toàn hệ thống 2 · Space Role Owner · AdminContributor · Reader(Lead / Senior / Member)phạm vi: theo từng Space 3 · Document ACL Visibility: private…publicSpecific users / groupsOwner overridephạm vi: từng tài liệu
Quyền hiệu lực = f(System Role, Space Role của user tại Space đó, ACL của chính tài liệu)
  • System Role (trên collection users): super_admin, admin, user.
  • Space Role (bảng memberships: user × space → role): owner, admin, contributor, reader. Một user có role khác nhau ở mỗi Space.
  • Document-level ACL: mỗi Article có visibility + danh sách sharedWith (user/role/space) — quyết định "ai được xem".
  • Dùng CASL (@casl/ability) trong NestJS: định nghĩa ability theo (action, subject) rồi PoliciesGuard kiểm tra ở từng route.
  • Actions chuẩn hoá: read · create · update · submit · review · approve · publish · archive · delete · manage.
  • Permission cache trong Redis (theo user+space) để không truy vấn membership mỗi request; invalidate khi role đổi.
  • Guard chạy theo thứ tự: JwtAuthGuardSpaceMemberGuardPoliciesGuard(CASL).

Ma trận quyền (rút gọn) Space scope

Hành độngReaderContributorSpace AdminOwner
Đọc tài liệu published
Tạo / sửa draft
Submit for review
Review / Approve / Publish
Quản lý thành viên & cấu trúc
Xoá Space / chuyển Owner

04 User & Org Management

  • CRUD user; profile (tên, avatar, chức danh, department chính).
  • Admin mời thành viên qua email (invite flow), gán System Role.
  • Groups / Teams (ngoài Department) để chia sẻ tài liệu theo nhóm chức năng chéo phòng ban.
  • Org chart nhẹ: user thuộc nhiều Space với role khác nhau (đã có ở membership).
  • Bulk import user từ CSV / đồng bộ từ Google Workspace directory.

05 Knowledge Space & Folder

  • CRUD Space (= Department): tên, slug, mô tả, icon, owner.
  • CRUD Folder lồng nhau (cây) bên trong Space; hỗ trợ kéo-thả sắp xếp (order field).
  • Di chuyển Article giữa các Folder / Space (kèm kiểm tra quyền).
  • Space templates: tạo Space mới từ mẫu (Engineering, HR…) có sẵn cấu trúc folder chuẩn.
  • Space homepage: trang tổng quan (pinned docs, thành viên, hoạt động gần đây).
  • Chống xoá nhầm: xoá Space/Folder là soft delete → thùng rác, khôi phục được.

06 Knowledge Article & Editor

  • Soạn Markdown: editor WYSIWYG/markdown (gợi ý: Tiptap hoặc Milkdown), lưu cả raw markdown + HTML render.
  • Upload file HTML và hiển thị nguyên trạng — xem mục Security về sandbox.
  • Upload & đính kèm PDF (xem inline qua viewer), ảnh, file văn phòng.
  • Autosave draft (debounce) + phục hồi bản nháp chưa lưu.
  • Content type field: markdown | html | pdf để FE render đúng.
  • Table of contents tự sinh từ heading; anchor link; breadcrumb theo cây folder.
  • Cross-link giữa các Article ([[wiki-link]]) + phát hiện broken link.
  • Cover / metadata: tiêu đề, mô tả ngắn, cover image, reading time.
  • Duplicate / template Article; xuất PDF/Markdown.

07 Lifecycle & Publishing Workflow

  • State machine: draft → pending_review → approved → published → archived (+ nhánh changes_requested, rejected).
  • Chuyển trạng thái được kiểm soát bằng quyền (Contributor submit; Space Admin approve/publish).
  • Submit for review → tạo bản ghi Review, gán reviewer, gửi notification.
  • Reviewer: Approve / Request Changes (kèm comment) / Reject; author revise rồi resubmit.
  • Chỉ áp workflow cho Official Knowledge; Personal Knowledge (My Notes) publish tự do, không review.
  • Multi-step approval tuỳ chọn (ví dụ Lead → Compliance) cho tài liệu nhạy cảm.
  • Scheduled publish & review reminder: tài liệu quá hạn cập nhật (vd 6 tháng) tự gắn cờ "cần review".
  • Enforce transition ở service layer (không cho FE tự set status tuỳ ý).

08 Versioning

  • Mỗi lần publish tạo immutable version snapshot trong article_versions.
  • Mỗi version lưu: version, author, reviewer, publishDate, changeSummary, nội dung tại thời điểm đó.
  • Diff giữa hai version (text diff cho markdown).
  • Rollback: khôi phục 1 version cũ thành draft mới (không phá lịch sử).
  • Phân biệt current published version (người đọc thấy) vs working draft (đang sửa).

09 Ownership & Visibility

  • OwnershipVisibility là hai field độc lập trên Article.
  • Visibility: private · specific_users · department · company_internal · public_link.
  • public_link: sinh token link chia sẻ chỉ-đọc, có thể đặt hạn / thu hồi / đặt mật khẩu.
  • Owner luôn có full quyền trên tài liệu bất kể visibility; đổi owner được (reassign).
  • Co-owners tuỳ chọn để tránh single point of failure.
  • Filter danh sách/tìm kiếm phải áp visibility ở tầng query (không lộ tài liệu private).

10 Comment · Tag · Notification

  • Comment trên Article (và inline theo đoạn nếu có thể); resolve/close comment.
  • @mention user → gửi notification.
  • Tag & Category: taxonomy để phân loại và lọc tài liệu.
  • Notification in-app (real-time qua WebSocket/SSE) + email (qua BullMQ): submit, approve, mention, changes requested, review reminder.
  • Reactions / "helpful?" feedback để đo chất lượng tài liệu.
  • Follow / watch Article hoặc Space để nhận cập nhật.
  • Notification preferences per user (channel, tần suất, digest theo ngày).

12 File & Storage

  • Upload trực tiếp lên Azure Blob Storage qua SAS URL có hạn (không đẩy file qua API server).
  • Chỉ lưu metadata (key, mime, size, checksum, uploader) trong Mongo, không lưu binary.
  • Giới hạn kích thước & whitelist mime; đặt tên/key ngẫu nhiên (tránh path traversal).
  • Virus/malware scan (ClamAV) trên file upload trước khi cho phép truy cập.
  • Truy cập file qua SAS URL có hạn theo quyền tài liệu (container không để public).
  • Sinh thumbnail/preview cho ảnh & trang đầu PDF.

13 Audit & Activity Log

  • Activity log mọi hành động quan trọng: create/edit/submit/approve/publish/permission change/login.
  • Ghi: actor, action, target (article/space), timestamp, IP/user-agent, diff tóm tắt.
  • Immutable audit (append-only) cho Official Knowledge — phục vụ compliance.
  • Activity feed theo Space & theo user; export log cho admin.

14 Security

⚠️ Rủi ro nghiêm trọng nhất — cho phép upload & hiển thị HTML

Hiển thị HTML người dùng upload = nguy cơ Stored XSS (đánh cắp session, mạo danh, leak tài liệu private). Bắt buộc xử lý ngay từ đầu:

  • Sanitize HTML server-side (sanitize-html / DOMPurify + jsdom) — whitelist tag/attr, loại bỏ <script>, on*, javascript:.
  • Render trong sandboxed iframe: sandbox KHÔNG bật allow-scripts + allow-same-origin cùng lúc; phục vụ từ domain/subdomain riêng (vd files.kms.company) để cô lập origin.
  • Content-Security-Policy chặt cho iframe content; Content-Disposition đúng cho file tải về.
  • Validation mọi input bằng DTO + class-validator; bật whitelist:true để loại field lạ.
  • Rate limiting (@nestjs/throttler + Redis) cho auth & API nhạy cảm.
  • Security headers: Helmet, HSTS, CORS whitelist origin FE.
  • NoSQL injection: không truyền object thô vào query; ép kiểu & validate ObjectId.
  • Secrets qua env/secret manager; không hardcode; xoay khoá JWT định kỳ.
  • Audit đăng nhập bất thường, khoá tạm sau N lần sai; encryption at rest cho storage & DB.
  • Phân quyền tải file: mọi SAS URL kiểm tra lại quyền tại thời điểm cấp.

15 Non-functional Requirements

Performance

  • Trang đọc SSR/ISR + cache Redis; API p95 < 300ms.
  • Pagination + cursor cho list lớn; index Mongo đầy đủ.

Scalability

  • API stateless (scale ngang); job tách qua queue.
  • Mongo replica set; đọc từ secondary khi cần.

Reliability

  • Backup DB & storage định kỳ; test restore.
  • Health check, graceful shutdown, retry job.

UX & A11y

  • i18n (VI/EN); responsive; dark mode.
  • Accessibility WCAG AA cho trang đọc.

Observability

  • Structured logging, request ID, error tracking (Sentry).
  • Metrics (Prometheus) + dashboard.

DevOps

  • Docker + CI/CD; migration script; seed data.
  • Staging/Prod tách biệt; env config.

16 MongoDB Data Model

Các collection chính, thiết kế xoay quanh Knowledge Article làm trung tâm:

CollectionField chính
usersemail, passwordHash, name, avatar, systemRole, status, twoFactor
spacesname, slug, description, icon, ownerId, isDeleted
membershipsuserId, spaceId, spaceRole (unique userId+spaceId)
foldersspaceId, parentId, name, order, path, isDeleted
articlesspaceId, folderId, title, slug, contentType, content, currentVersion, status, ownerId, visibility, sharedWith[], tags[], categoryId, type (personal|official)
article_versionsarticleId, version, content, authorId, reviewerId, publishDate, changeSummary
attachmentsarticleId, storageKey, mime, size, checksum, uploaderId
reviewsarticleId, reviewerId, status, comment, createdAt
approvalsarticleId, approverId, decision, step, decidedAt
commentsarticleId, authorId, body, anchor, resolved, parentId
tags / categoriesname, slug, spaceId?
notificationsuserId, type, payload, read, createdAt
activity_logsactorId, action, targetType, targetId, meta, ip, createdAt
Index gợi ý: articles: (spaceId, status), (ownerId), text index / Azure AI Search cho title+content; memberships: unique (userId, spaceId); activity_logs: (targetId, createdAt).
// articles — schema rút gọn (Mongoose)
{
  spaceId: ObjectId, folderId: ObjectId,
  title: String, slug: String,
  contentType: 'markdown' | 'html' | 'pdf',
  content: String,            // markdown raw / sanitized html / null
  currentVersion: Number,
  status: 'draft'|'pending_review'|'approved'|'published'|'archived',
  type: 'personal' | 'official',
  ownerId: ObjectId,
  visibility: 'private'|'specific_users'|'department'|'company_internal'|'public_link',
  sharedWith: [{ kind: 'user'|'space'|'role', refId: ObjectId }],
  tags: [String], categoryId: ObjectId,
  createdAt, updatedAt
}

17 API Design (REST)

  • Chuẩn REST, /api/v1, JSON, pagination (?page&limit hoặc cursor), filter & sort chuẩn hoá.
  • Swagger/OpenAPI tự sinh; mã lỗi thống nhất ({ code, message, details }).
NhómEndpoint tiêu biểu
AuthPOST /auth/login · /auth/refresh · /auth/logout · GET /auth/me · /auth/google
SpacesGET/POST /spaces · GET/PATCH/DELETE /spaces/:id · GET /spaces/:id/members
FoldersGET/POST /spaces/:id/folders · PATCH/DELETE /folders/:id
ArticlesGET/POST /articles · GET/PATCH/DELETE /articles/:id
WorkflowPOST /articles/:id/submit · /review · /approve · /publish · /archive
VersionsGET /articles/:id/versions · GET /versions/:id/diff · POST /versions/:id/rollback
FilesPOST /uploads/presign · POST /articles/:id/attachments
CollabGET/POST /articles/:id/comments · GET /notifications
SearchGET /search?q=&space=&owner=&tag=&type=

18 AI-ready (chuẩn bị từ đầu)

  • Khi Article publish → job sinh embeddings theo chunk, lưu & đánh index vào Azure AI Search (vector index).
  • RAG endpoint: POST /ai/ask → retrieve theo permission của user → tổng hợp câu trả lời kèm nguồn (link Article).
  • Metadata sạch (department, category, tags, owner) giúp AI lọc & trích dẫn chính xác.
  • AI chỉ truy xuất tài liệu user được phép xem — áp permission ở bước retrieve (tránh leak).
  • Tính năng phụ: auto-summary, auto-tag, gợi ý tài liệu liên quan, phát hiện trùng lặp.

19 Gợi ý Project Structure

Không dùng monorepo — backend và frontend là hai repo/project tách riêng. Tên module/thư mục đặt theo đúng domain của KMS (số nhiều, kebab-case) để nhìn là biết chứa gì:

NestJS — Backend API

src/
  modules/
    auth/               # xác thực: JWT, OAuth, guards
    users/              # người dùng & hồ sơ
    spaces/             # Knowledge Space (phòng ban)
    memberships/        # vai trò user trong Space
    folders/            # cây thư mục trong Space
    articles/           # Knowledge Article + trạng thái
    article-versions/   # lịch sử phiên bản
    reviews/            # duyệt & phê duyệt (workflow)
    attachments/        # file đính kèm (Azure Blob)
    comments/           # bình luận & @mention
    taxonomy/           # tag & category
    search/             # Azure AI Search
    notifications/      # thông báo in-app + email
    activity-log/       # audit / nhật ký
    ai/                 # embeddings, RAG
  common/               # guards, CASL, interceptors,
                        # filters, pipes, decorators
  shared/               # DTO base, types, constants, utils
  config/               # cấu hình & env
  main.ts

Next.js — Frontend

src/
  app/
    (auth)/login/
    (app)/
      spaces/[spaceSlug]/
        folders/[folderId]/
          articles/[articleSlug]/
      my-notes/
      search/
      admin/
      layout.tsx
  components/
    editor/       # Markdown editor
    viewer/       # HTML sandbox viewer
    workflow/     # UI duyệt bài
    ui/           # design system chung
  features/       # logic theo domain
  lib/api/        # typed API client
  hooks/
  types/          # type khớp DTO backend
  middleware.ts   # chặn route chưa auth

Cấu trúc chuẩn của một module NestJS

modules/articles/
  articles.module.ts
  articles.controller.ts                # thin — chỉ nhận request/response
  articles.service.ts                   # business logic
  articles.repository.ts                # truy cập Mongo (tuỳ chọn)
  dtos/
    requests/
      create-article.request.dto.ts     # validate bằng class-validator
      update-article.request.dto.ts
    responses/
      article.response.dto.ts           # shape dữ liệu trả về
  schemas/
    article.schema.ts                   # Mongoose schema
  articles.service.spec.ts              # unit test

Quy ước code & cấu trúc bắt buộc tuân thủ

  • Naming nhất quán: file kebab-case, class PascalCase, biến/hàm camelCase, hằng UPPER_SNAKE; module đặt theo domain (số nhiều) thống nhất.
  • Thin controller, fat service: controller chỉ điều phối request; business logic ở service; truy cập DB tách qua repository/model.
  • Module đủ bộ: mỗi module NestJS gồm module · controller · service · dto · schema; không nhét logic hay query vào controller.
  • ESLint + Prettier + EditorConfig chung cho cả team; format tự động khi save và ở pre-commit.
  • Conventional Commits + husky + lint-staged — chặn commit không đạt lint/test.
  • Path alias (@modules, @common, @/…) thay cho import tương đối dài ../../../.
  • Tách layer rõ ràng (controller → service → repository), không gọi model trực tiếp trong controller.
  • Type dùng chung FE/BE: sinh type từ OpenAPI/Swagger để frontend khớp đúng DTO backend.
  • Barrel export (index.ts) hợp lý; tránh circular import.
  • Test đặt cạnh file (*.spec.ts): unit test cho service, e2e cho luồng API chính.

20 Roadmap / Đề xuất MVP

PhasePhạm vi
MVPAuth (email + Google SSO), Spaces + Folders, Article markdown, upload HTML/PDF có sandbox, System + Space roles, visibility cơ bản, publish workflow (1 bước review), full-text search cơ bản, activity log.
V2Versioning + diff + rollback, comments/@mention, notifications real-time, tag/category taxonomy, public link, personal vs official rõ ràng, review reminder.
V3AI search/RAG, multi-step approval, advanced analytics, Azure AI Search nâng cao (semantic + vector), SSO nâng cao + SCIM, audit compliance.
Bắt đầu nhỏ nhưng giữ đúng data model quanh Knowledge Article + Version + Permission ngay từ MVP — để V2/V3 mở rộng mà không phải migrate lớn.