🎯 Goal
Implement API GET /analytics/network/topology để trả về dữ liệu graph topology dạng nodes và edges.
API này phục vụ các widget phụ phía dưới:
- Conceptual Proximity
- Global Collaboration Network
Mục tiêu là cung cấp cấu trúc đồ thị mạng lưới để FE dựng sơ đồ kết nối không gian, bao gồm:
- Các node đại diện cho keyword / topic / author / institution
- Các edge đại diện cho quan hệ liên kết, độ gần khái niệm hoặc hợp tác nghiên cứu
- Trọng số
weight để FE biểu diễn độ mạnh/yếu của kết nối
🖼️ UI Mapping
UI Blocks
Conceptual Proximity
Global Collaboration Network
Chart Type
Network graph / Force-directed graph / Spatial topology graph
Description
API trả về graph topology gồm:
nodes = danh sách thực thể
edges = danh sách liên kết giữa các thực thể
Ví dụ:
LLMs -------------- Ethics
AI Safety --------- Bias Detection
Author A ---------- Institution B
📡 Endpoint
GET /analytics/network/topology
📥 Query Parameters
| Param |
Type |
Required |
Description |
project_id |
string / number |
Yes |
ID của project cần lấy network topology |
network_type |
string |
No |
Loại network cần lấy. Values: conceptual, collaboration, all. Default: all |
subject_area |
string |
No |
Lọc hẹp thêm theo subject area cụ thể |
keywords |
string[] / comma-separated |
No |
Lọc hẹp thêm theo danh sách keyword |
from_year |
number |
No |
Năm bắt đầu lọc dữ liệu |
to_year |
number |
No |
Năm kết thúc lọc dữ liệu |
limit_nodes |
number |
No |
Số lượng node tối đa. Default: 50 |
min_weight |
number |
No |
Chỉ lấy edge có weight tối thiểu. Default: 0.1 |
✅ Example Requests
1. Fetch all topology by project only
GET /analytics/network/topology?project_id=PROJECT_ID
2. Fetch conceptual proximity only
GET /analytics/network/topology?project_id=PROJECT_ID&network_type=conceptual
3. Fetch collaboration network only
GET /analytics/network/topology?project_id=PROJECT_ID&network_type=collaboration
4. Fetch topology with keywords filter
GET /analytics/network/topology?project_id=PROJECT_ID&keywords=LLM,RAG,AI Safety
5. Fetch topology with limits
GET /analytics/network/topology?project_id=PROJECT_ID&limit_nodes=40&min_weight=0.3
🧾 Response Contract
{
"code": 200,
"message": "Fetch network topology successfully",
"data": {
"nodes": [
{
"id": "n1",
"label": "LLMs",
"size": 20
},
{
"id": "n2",
"label": "Ethics",
"size": 15
}
],
"edges": [
{
"from": "n1",
"to": "n2",
"weight": 0.82
}
]
}
}
📌 Response Field Explanation
Node
| Field |
Type |
Description |
id |
string |
Unique ID của node |
label |
string |
Tên hiển thị của node |
size |
number |
Kích thước node trên graph |
Edge
| Field |
Type |
Description |
from |
string |
ID node nguồn |
to |
string |
ID node đích |
weight |
number |
Độ mạnh liên kết giữa 2 node |
✅ Optional Extended Response Fields
FE hiện tại chỉ cần id, label, size, from, to, weight.
Tuy nhiên BE có thể bổ sung thêm các field sau nếu cần mà không phá contract:
{
"id": "kw_001",
"label": "LLMs",
"type": "KEYWORD",
"size": 20,
"color": "#FF6B00"
}
{
"from": "kw_001",
"to": "kw_002",
"weight": 0.82,
"type": "CONCEPTUAL_PROXIMITY",
"label": "0.82 proximity"
}
🧠 Business Logic
1. Project-based filtering
API bắt buộc nhận project_id.
Từ project_id, hệ thống cần lấy scope nghiên cứu của project:
- Subject area của project
- Subject categories thuộc subject area đó
- Keywords project đang theo dõi
Sau đó dùng scope này để lọc tập bài báo trước khi build network topology.
Ví dụ project đang theo dõi:
{
"project_id": 1,
"subject_area": "Artificial Intelligence",
"subject_categories": ["Computer Science Applications", "Artificial Intelligence"],
"keywords": ["LLM", "RAG", "Machine Learning"]
}
API chỉ build graph trên dữ liệu thuộc scope này.
2. Filter priority
Nếu client chỉ truyền:
API tự động lấy toàn bộ subject area, subject categories và keywords của project để lọc.
Nếu client truyền thêm:
API sẽ lọc hẹp hơn trong phạm vi project.
Ví dụ:
GET /analytics/network/topology?project_id=1&subject_area=AI&keywords=LLM,RAG
Kết quả chỉ build network trên dữ liệu:
- Thuộc project scope
- Thuộc subject area
AI
- Có keyword liên quan đến
LLM hoặc RAG
3. Network type logic
API hỗ trợ 3 chế độ:
conceptual
collaboration
all
network_type = conceptual
Build network từ quan hệ gần nhau về mặt khái niệm giữa:
- Keyword
- Topic
- Subject category
Ví dụ:
LLMs -> Ethics
AI Safety -> Bias Detection
Quantum Sim -> Physics
network_type = collaboration
Build network từ quan hệ hợp tác giữa:
- Author
- Institution
- Country nếu có dữ liệu
Ví dụ:
Dr. Helena Vance -> Stanford Bio-Dynamics Lab
Author A -> Author B
Institution A -> Institution B
network_type = all
Kết hợp cả:
conceptual network + collaboration network
4. Conceptual proximity node logic
Với network_type=conceptual, node nên lấy từ:
Keyword
Topic
Subject_Category
Suggested phase 1:
Use Keyword and Topic as nodes
Node example:
{
"id": "kw_001",
"label": "LLMs",
"size": 20
}
Node size calculation:
size = 10 + min(article_count * 2, 30)
Hoặc normalize theo volume:
size = normalized(article_count, min=10, max=40)
5. Conceptual proximity edge logic
Edge giữa 2 keyword/topic được tạo khi chúng cùng xuất hiện trong cùng bài báo hoặc có liên hệ qua topic/sub-topic.
Suggested phase 1:
weight = co_occurrence_count / max_co_occurrence_count
Trong đó:
co_occurrence_count = số bài báo mà 2 keyword/topic cùng xuất hiện
Yêu cầu normalize:
weight nằm trong khoảng 0 đến 1
Ví dụ:
{
"from": "kw_001",
"to": "kw_002",
"weight": 0.82
}
6. Collaboration network node logic
Với network_type=collaboration, node nên lấy từ:
Suggested phase 1 nếu chưa có institution data:
Node size calculation:
size = 10 + min(article_count * 2, 30)
Hoặc:
size = normalized(article_count + citation_count, min=10, max=40)
7. Collaboration network edge logic
Edge được tạo từ quan hệ hợp tác nghiên cứu.
Supported phase 1:
| Edge |
Meaning |
| Author -> Author |
Hai tác giả cùng viết một hoặc nhiều bài báo |
| Author -> Institution |
Tác giả thuộc / hợp tác với institution |
| Institution -> Institution |
Hai institution cùng xuất hiện trong bài báo |
Suggested phase 1:
weight = co_author_article_count
Có thể normalize về 0-1 nếu FE muốn dùng cùng scale với conceptual.
Recommended for current contract:
weight = normalized collaboration strength from 0 to 1
8. Edge canonicalization
Để tránh duplicate:
phải merge thành một edge duy nhất.
Suggested rule:
from = smaller node id
to = larger node id
Nếu duplicate edge:
weight = merged / normalized value
9. Graph limiting rule
Để FE không bị quá tải:
limit_nodes default = 50
limit_nodes max = 150
Suggested logic:
1. Tính importance của node
2. Chọn top N nodes
3. Chỉ giữ edge có cả from và to nằm trong selected nodes
4. Apply min_weight
5. Sort edges by weight DESC
Node importance có thể tính bằng:
article_count + citation_count + degree_count
10. Weight normalization
Vì API có thể trộn conceptual và collaboration, nên chuẩn hóa edge weight về:
Suggested formula:
weight = rawWeight / maxRawWeight
Round:
round to 2 decimal places
Nếu maxRawWeight = 0:
11. Data validation rule
Response phải đảm bảo:
nodes là array
edges là array
- Node
id không null
- Node
label không null
- Node
size là number
- Edge
from và to trỏ tới node tồn tại
- Edge
from !== to
- Edge
weight là number
- Không có
NaN
- Không có duplicate node
- Không có duplicate edge
- Không có reverse duplicate edge
📦 Data Source
API có thể lấy dữ liệu từ các bảng hiện tại:
Project
Project_Keyword
Subject_Area
Subject_Category
Topic
Sub_Topic
Keyword
Keyword_Article
Article
Author
Author_Article
Institution
Author_Institution
Relevant schema flow:
Project.subject_area -> Subject_Area.subject_area_id
Subject_Category.subject_area_id -> Subject_Area.subject_area_id
Article.primary_topic -> Topic.topic_id
Topic.subject_category_id -> Subject_Category.subject_category_id
Sub_Topic.article_id -> Article.article_id
Sub_Topic.topic_id -> Topic.topic_id
Keyword_Article.article_id -> Article.article_id
Keyword_Article.keyword_id -> Keyword.keyword_id
Project_Keyword.keyword_id -> Keyword.keyword_id
Author_Article.article_id -> Article.article_id
Author_Article.author_id -> Author.author_id
Author -> Author_Institution -> Institution
🧮 Suggested Query Logic
1. Resolve project scope
project_id
-> subject_area
-> subject_category_ids
-> keyword_ids
2. Filter related articles
Article match nếu thỏa mãn ít nhất một trong các điều kiện:
Article.primary_topic thuộc subject_category_ids
OR Article có Sub_Topic thuộc subject_category_ids
OR Article có Keyword_Article thuộc project keyword_ids
3. Build conceptual graph
For each filtered article:
collect keywords/topics
create nodes
create pairwise co-occurrence edges
4. Build collaboration graph
For each filtered article:
collect authors/institutions
create nodes
create pairwise collaboration edges
5. Merge graph
Nếu network_type=all:
nodes = conceptual nodes + collaboration nodes
edges = conceptual edges + collaboration edges
6. Normalize and limit
normalize node size
normalize edge weight
apply limit_nodes
apply min_weight
⚠️ Edge Cases
1. Project not found
Nếu project_id không tồn tại:
{
"code": 404,
"message": "Project not found",
"data": null
}
2. Project has no scope
Nếu project chưa có subject area hoặc keywords:
{
"code": 200,
"message": "Fetch network topology successfully",
"data": {
"nodes": [],
"edges": []
}
}
3. Empty filtered dataset
Nếu filter xong không có bài báo phù hợp:
{
"code": 200,
"message": "Fetch network topology successfully",
"data": {
"nodes": [],
"edges": []
}
}
4. Invalid network_type
Nếu network_type không thuộc:
conceptual
collaboration
all
Response:
{
"code": 400,
"message": "Invalid network_type",
"data": null
}
5. Article has only one node
Nếu một article chỉ có một keyword/topic/author hợp lệ:
- Vẫn có thể tạo node
- Không tạo edge từ article đó
6. Missing node label
Nếu label bị thiếu:
hoặc bỏ qua node tùy convention.
Suggested phase 1:
7. Edge references missing node
Nếu edge có from hoặc to không nằm trong selected nodes:
8. Invalid year range
Nếu from_year > to_year:
{
"code": 400,
"message": "Invalid year range",
"data": null
}
9. Invalid limit_nodes
Nếu limit_nodes <= 0 hoặc không phải number:
{
"code": 400,
"message": "Invalid limit_nodes",
"data": null
}
Suggested max:
10. Invalid min_weight
Nếu min_weight < 0 hoặc không phải number:
{
"code": 400,
"message": "Invalid min_weight",
"data": null
}
🧪 Acceptance Criteria
🧪 Test Cases
TC-01: Fetch all topology by project_id only
Request
GET /analytics/network/topology?project_id=1
Expected
- API lấy project scope
- Filter bài báo theo project scope
- Build conceptual graph
- Build collaboration graph
- Merge nodes and edges
- Response đúng contract
TC-02: Fetch conceptual network only
Request
GET /analytics/network/topology?project_id=1&network_type=conceptual
Expected
- Nodes là keyword/topic/concept
- Edges là conceptual proximity/co-occurrence
- Không trả author/institution nodes nếu không cần
TC-03: Fetch collaboration network only
Request
GET /analytics/network/topology?project_id=1&network_type=collaboration
Expected
- Nodes là author/institution
- Edges là quan hệ collaboration
- Không trả keyword/topic nodes nếu không cần
TC-04: Fetch topology with keywords filter
Request
GET /analytics/network/topology?project_id=1&keywords=LLM,RAG
Expected
- Chỉ lấy bài báo có keyword liên quan đến
LLM hoặc RAG
- Nodes và edges vẫn hợp lệ
- Không có edge trỏ tới node không tồn tại
TC-05: Article with multiple keywords
Input
Article có keywords:
Expected
Tạo nodes:
Tạo edges:
LLMs - Ethics
LLMs - Bias
Ethics - Bias
TC-06: Duplicate conceptual edge
Input
LLMs và Ethics cùng xuất hiện trong 5 bài.
Expected
Chỉ trả 1 edge:
{
"from": "kw_ethics",
"to": "kw_llms",
"weight": 1
}
Sau khi normalize, weight nằm trong khoảng 0 đến 1.
TC-07: Edge references selected nodes only
Input
Sau khi apply limit_nodes, node n3 bị loại.
Expected
Mọi edge có from=n3 hoặc to=n3 phải bị loại.
TC-08: Invalid network_type
Request
GET /analytics/network/topology?project_id=1&network_type=invalid
Expected
{
"code": 400,
"message": "Invalid network_type",
"data": null
}
TC-09: Project not found
Request
GET /analytics/network/topology?project_id=999
Expected
{
"code": 404,
"message": "Project not found",
"data": null
}
TC-10: Empty filtered dataset
Request
GET /analytics/network/topology?project_id=1&keywords=unknown-keyword
Expected
{
"code": 200,
"message": "Fetch network topology successfully",
"data": {
"nodes": [],
"edges": []
}
}
TC-11: Invalid year range
Request
GET /analytics/network/topology?project_id=1&from_year=2026&to_year=2021
Expected
{
"code": 400,
"message": "Invalid year range",
"data": null
}
TC-12: Invalid limit_nodes
Request
GET /analytics/network/topology?project_id=1&limit_nodes=-1
Expected
{
"code": 400,
"message": "Invalid limit_nodes",
"data": null
}
TC-13: Invalid min_weight
Request
GET /analytics/network/topology?project_id=1&min_weight=-1
Expected
{
"code": 400,
"message": "Invalid min_weight",
"data": null
}
📌 Implementation Notes
Nên tách logic thành các phần riêng:
Controller
-> validate query params
Service
-> get project tracking scope
-> filter related articles
-> build conceptual nodes and edges
-> build collaboration nodes and edges
-> merge graph by network_type
-> normalize node sizes
-> normalize edge weights
-> apply limits
-> build response contract
Gợi ý function:
getProjectTrackingScope(projectId)
buildArticleScopeFilter(scope, queryParams)
getFilteredArticles(scope, filters)
buildConceptualNodes(filteredArticles)
buildConceptualEdges(filteredArticles)
buildCollaborationNodes(filteredArticles)
buildCollaborationEdges(filteredArticles)
mergeTopologyGraphs(graphs)
normalizeNodeSizes(nodes)
normalizeEdgeWeights(edges)
applyTopologyLimits(nodes, edges, limitNodes, minWeight)
buildNetworkTopologyResponse(nodes, edges)
📦 Suggested Mock Data
const mockNetworkTopology = {
nodes: [
{
id: "kw_llms",
label: "LLMs",
size: 20
},
{
id: "kw_ethics",
label: "Ethics",
size: 15
},
{
id: "kw_bias",
label: "Bias",
size: 18
}
],
edges: [
{
from: "kw_llms",
to: "kw_ethics",
weight: 0.82
},
{
from: "kw_llms",
to: "kw_bias",
weight: 0.64
}
]
};
🚀 Future Improvements
KEYWORD
TOPIC
AUTHOR
INSTITUTION
COUNTRY
CONCEPTUAL_PROXIMITY
CO_OCCURRENCE
CO_AUTHORSHIP
AFFILIATION
- Add node color by type
- Add edge label
- Add fixed x/y coordinates for deterministic layout
- Add community / cluster detection
- Add graph density score
- Add centrality metrics:
- degree centrality
- betweenness centrality
- closeness centrality
- Add
metric_type=co_occurrence|citation_weighted|semantic_similarity
- Add Redis caching:
analytics:network:topology:{project_id}:{network_type}:{subject_area}:{keywords}:{from_year}:{to_year}:{limit_nodes}:{min_weight}
- Optimize query with indexes on:
project_id
publication_year
article_id
author_id
keyword_id
topic_id
subject_category_id
🎯 Goal
Implement API
GET /analytics/network/topologyđể trả về dữ liệu graph topology dạng nodes và edges.API này phục vụ các widget phụ phía dưới:
Mục tiêu là cung cấp cấu trúc đồ thị mạng lưới để FE dựng sơ đồ kết nối không gian, bao gồm:
weightđể FE biểu diễn độ mạnh/yếu của kết nối🖼️ UI Mapping
UI Blocks
Chart Type
Description
API trả về graph topology gồm:
Ví dụ:
📡 Endpoint
📥 Query Parameters
project_idnetwork_typeconceptual,collaboration,all. Default:allsubject_areakeywordsfrom_yearto_yearlimit_nodes50min_weight0.1✅ Example Requests
1. Fetch all topology by project only
2. Fetch conceptual proximity only
3. Fetch collaboration network only
4. Fetch topology with keywords filter
5. Fetch topology with limits
🧾 Response Contract
{ "code": 200, "message": "Fetch network topology successfully", "data": { "nodes": [ { "id": "n1", "label": "LLMs", "size": 20 }, { "id": "n2", "label": "Ethics", "size": 15 } ], "edges": [ { "from": "n1", "to": "n2", "weight": 0.82 } ] } }📌 Response Field Explanation
Node
idlabelsizeEdge
fromtoweight✅ Optional Extended Response Fields
FE hiện tại chỉ cần
id,label,size,from,to,weight.Tuy nhiên BE có thể bổ sung thêm các field sau nếu cần mà không phá contract:
{ "id": "kw_001", "label": "LLMs", "type": "KEYWORD", "size": 20, "color": "#FF6B00" }{ "from": "kw_001", "to": "kw_002", "weight": 0.82, "type": "CONCEPTUAL_PROXIMITY", "label": "0.82 proximity" }🧠 Business Logic
1. Project-based filtering
API bắt buộc nhận
project_id.Từ
project_id, hệ thống cần lấy scope nghiên cứu của project:Sau đó dùng scope này để lọc tập bài báo trước khi build network topology.
Ví dụ project đang theo dõi:
{ "project_id": 1, "subject_area": "Artificial Intelligence", "subject_categories": ["Computer Science Applications", "Artificial Intelligence"], "keywords": ["LLM", "RAG", "Machine Learning"] }API chỉ build graph trên dữ liệu thuộc scope này.
2. Filter priority
Nếu client chỉ truyền:
project_idAPI tự động lấy toàn bộ subject area, subject categories và keywords của project để lọc.
Nếu client truyền thêm:
API sẽ lọc hẹp hơn trong phạm vi project.
Ví dụ:
Kết quả chỉ build network trên dữ liệu:
AILLMhoặcRAG3. Network type logic
API hỗ trợ 3 chế độ:
network_type = conceptual
Build network từ quan hệ gần nhau về mặt khái niệm giữa:
Ví dụ:
network_type = collaboration
Build network từ quan hệ hợp tác giữa:
Ví dụ:
network_type = all
Kết hợp cả:
4. Conceptual proximity node logic
Với
network_type=conceptual, node nên lấy từ:Suggested phase 1:
Node example:
{ "id": "kw_001", "label": "LLMs", "size": 20 }Node size calculation:
size = 10 + min(article_count * 2, 30)Hoặc normalize theo volume:
5. Conceptual proximity edge logic
Edge giữa 2 keyword/topic được tạo khi chúng cùng xuất hiện trong cùng bài báo hoặc có liên hệ qua topic/sub-topic.
Suggested phase 1:
Trong đó:
Yêu cầu normalize:
Ví dụ:
{ "from": "kw_001", "to": "kw_002", "weight": 0.82 }6. Collaboration network node logic
Với
network_type=collaboration, node nên lấy từ:Suggested phase 1 nếu chưa có institution data:
Node size calculation:
size = 10 + min(article_count * 2, 30)Hoặc:
7. Collaboration network edge logic
Edge được tạo từ quan hệ hợp tác nghiên cứu.
Supported phase 1:
Suggested phase 1:
Có thể normalize về
0-1nếu FE muốn dùng cùng scale với conceptual.Recommended for current contract:
8. Edge canonicalization
Để tránh duplicate:
phải merge thành một edge duy nhất.
Suggested rule:
Nếu duplicate edge:
9. Graph limiting rule
Để FE không bị quá tải:
Suggested logic:
Node importance có thể tính bằng:
10. Weight normalization
Vì API có thể trộn conceptual và collaboration, nên chuẩn hóa edge weight về:
Suggested formula:
Round:
Nếu
maxRawWeight = 0:11. Data validation rule
Response phải đảm bảo:
nodeslà arrayedgeslà arrayidkhông nulllabelkhông nullsizelà numberfromvàtotrỏ tới node tồn tạifrom !== toweightlà numberNaN📦 Data Source
API có thể lấy dữ liệu từ các bảng hiện tại:
Relevant schema flow:
🧮 Suggested Query Logic
1. Resolve project scope
2. Filter related articles
Article match nếu thỏa mãn ít nhất một trong các điều kiện:
3. Build conceptual graph
4. Build collaboration graph
5. Merge graph
Nếu
network_type=all:6. Normalize and limit
1. Project not found
Nếu
project_idkhông tồn tại:{ "code": 404, "message": "Project not found", "data": null }2. Project has no scope
Nếu project chưa có subject area hoặc keywords:
{ "code": 200, "message": "Fetch network topology successfully", "data": { "nodes": [], "edges": [] } }3. Empty filtered dataset
Nếu filter xong không có bài báo phù hợp:
{ "code": 200, "message": "Fetch network topology successfully", "data": { "nodes": [], "edges": [] } }4. Invalid network_type
Nếu
network_typekhông thuộc:Response:
{ "code": 400, "message": "Invalid network_type", "data": null }5. Article has only one node
Nếu một article chỉ có một keyword/topic/author hợp lệ:
6. Missing node label
Nếu label bị thiếu:
hoặc bỏ qua node tùy convention.
Suggested phase 1:
7. Edge references missing node
Nếu edge có
fromhoặctokhông nằm trong selected nodes:8. Invalid year range
Nếu
from_year > to_year:{ "code": 400, "message": "Invalid year range", "data": null }9. Invalid limit_nodes
Nếu
limit_nodes <= 0hoặc không phải number:{ "code": 400, "message": "Invalid limit_nodes", "data": null }Suggested max:
10. Invalid min_weight
Nếu
min_weight < 0hoặc không phải number:{ "code": 400, "message": "Invalid min_weight", "data": null }🧪 Acceptance Criteria
project_idnetwork_type=conceptualnetwork_type=collaborationnetwork_type=allsubject_areakeywordsfrom_yearvàto_yearlimit_nodesmin_weightdata.nodesdata.edgesid,label,sizefrom,to,weightidkhông nulllabelkhông nullsizeluôn là numberfromvàtođều tồn tại trong nodesfrom !== toweightluôn là numberweight >= 0NaNtrong response{ nodes: [], edges: [] }100ms🧪 Test Cases
TC-01: Fetch all topology by project_id only
Request
Expected
TC-02: Fetch conceptual network only
Request
Expected
TC-03: Fetch collaboration network only
Request
Expected
TC-04: Fetch topology with keywords filter
Request
Expected
LLMhoặcRAGTC-05: Article with multiple keywords
Input
Article có keywords:
Expected
Tạo nodes:
Tạo edges:
TC-06: Duplicate conceptual edge
Input
LLMsvàEthicscùng xuất hiện trong 5 bài.Expected
Chỉ trả 1 edge:
{ "from": "kw_ethics", "to": "kw_llms", "weight": 1 }Sau khi normalize,
weightnằm trong khoảng0đến1.TC-07: Edge references selected nodes only
Input
Sau khi apply
limit_nodes, noden3bị loại.Expected
Mọi edge có
from=n3hoặcto=n3phải bị loại.TC-08: Invalid network_type
Request
Expected
{ "code": 400, "message": "Invalid network_type", "data": null }TC-09: Project not found
Request
Expected
{ "code": 404, "message": "Project not found", "data": null }TC-10: Empty filtered dataset
Request
Expected
{ "code": 200, "message": "Fetch network topology successfully", "data": { "nodes": [], "edges": [] } }TC-11: Invalid year range
Request
Expected
{ "code": 400, "message": "Invalid year range", "data": null }TC-12: Invalid limit_nodes
Request
Expected
{ "code": 400, "message": "Invalid limit_nodes", "data": null }TC-13: Invalid min_weight
Request
Expected
{ "code": 400, "message": "Invalid min_weight", "data": null }📌 Implementation Notes
Nên tách logic thành các phần riêng:
Gợi ý function:
📦 Suggested Mock Data
🚀 Future Improvements
type:type:metric_type=co_occurrence|citation_weighted|semantic_similarityanalytics:network:topology:{project_id}:{network_type}:{subject_area}:{keywords}:{from_year}:{to_year}:{limit_nodes}:{min_weight}project_idpublication_yeararticle_idauthor_idkeyword_idtopic_idsubject_category_id