1+ digraph G {
2+ rankdir =TB;
3+ node [shape =box , style =rounded];
4+
5+ subgraph cluster_External_APIs {
6+ label =" External APIs" ;
7+ style =rounded;
8+ EUPMC_API [label =" Europe PMC API" ];
9+ ARXIV_API [label =" arXiv API" ];
10+ CROSSREF_API [label =" Crossref API" ];
11+ OPENALEX_API [label =" OpenAlex API" ];
12+ BIORXIV_WEB [label =" BioRxiv Web" ];
13+ MEDRXIV_WEB [label =" MedRxiv Web" ];
14+ REDALYC_WEB [label =" Redalyc Web" ];
15+ }
16+
17+ subgraph cluster_Presentation_Layer {
18+ label =" Presentation Layer" ;
19+ style =rounded;
20+ ST [label =" Streamlit UI\n streamlit_app.py\n ~500 lines" ];
21+ CLI [label =" CLI Interface\n pygetpapers_cli.py" ];
22+ API [label =" REST API\n pygetpapers_api.py" ];
23+ }
24+
25+ subgraph cluster_Service_Layer {
26+ label =" Service Layer" ;
27+ style =rounded;
28+ SS [label =" Search Service\n services/search_service.py" ];
29+ CS [label =" Corpus Service\n services/corpus_service.py" ];
30+ FS [label =" File Service\n services/file_service.py" ];
31+ MS [label =" Metadata Service\n services/metadata_service.py" ];
32+ }
33+
34+ subgraph cluster_Repository_Layer {
35+ label =" Repository Layer" ;
36+ style =rounded;
37+ RI [label =" Repository Interface\n repositories/base.py" ];
38+ }
39+
40+ subgraph cluster_Repository_Implementations {
41+ label =" Repository Implementations" ;
42+ style =rounded;
43+ EUPMC [label =" Europe PMC\n repositories/europe_pmc.py" ];
44+ ARXIV [label =" arXiv\n repositories/arxiv.py" ];
45+ CROSSREF [label =" Crossref\n repositories/crossref.py" ];
46+ OPENALEX [label =" OpenAlex\n repositories/openalex.py" ];
47+ BIORXIV [label =" BioRxiv\n repositories/biorxiv.py" ];
48+ MEDRXIV [label =" MedRxiv\n repositories/medrxiv.py" ];
49+ REDALYC [label =" Redalyc\n repositories/redalyc.py" ];
50+ }
51+
52+ subgraph cluster_Web_Scraping_Layer {
53+ label =" Web Scraping Layer" ;
54+ style =rounded;
55+ WS [label =" Web Scraper Base\n scrapers/base_scraper.py" ];
56+ }
57+
58+ subgraph cluster_Scraper_Implementations {
59+ label =" Scraper Implementations" ;
60+ style =rounded;
61+ BS [label =" BioRxiv Scraper\n scrapers/biorxiv_scraper.py" ];
62+ MS [label =" MedRxiv Scraper\n scrapers/medrxiv_scraper.py" ];
63+ RS [label =" Redalyc Scraper\n scrapers/redalyc_scraper.py" ];
64+ }
65+
66+ subgraph cluster_Data_Processing_Layer {
67+ label =" Data Processing Layer" ;
68+ style =rounded;
69+ PARSER [label =" Content Parser\n processors/content_parser.py" ];
70+ CONVERTER [label =" Format Converter\n processors/format_converter.py" ];
71+ VALIDATOR [label =" Data Validator\n processors/data_validator.py" ];
72+ }
73+
74+ subgraph cluster_Storage_Layer {
75+ label =" Storage Layer" ;
76+ style =rounded;
77+ FS_STORAGE [label =" File Storage\n storage/file_storage.py" ];
78+ DB [label =" Database\n storage/database.py" ];
79+ CACHE [label =" Cache\n storage/cache.py" ];
80+ }
81+
82+ // Edges
83+ ST -> SS;
84+ ST -> CS;
85+ ST -> FS;
86+ ST -> MS;
87+ CLI -> SS;
88+ CLI -> CS;
89+ API -> SS;
90+ API -> CS;
91+ SS -> RI;
92+ CS -> RI;
93+ FS -> FS_STORAGE;
94+ MS -> DB;
95+ RI -> EUPMC;
96+ RI -> ARXIV;
97+ RI -> CROSSREF;
98+ RI -> OPENALEX;
99+ RI -> BIORXIV;
100+ RI -> MEDRXIV;
101+ RI -> REDALYC;
102+ BIORXIV -> WS;
103+ MEDRXIV -> WS;
104+ REDALYC -> WS;
105+ WS -> BS;
106+ WS -> MS;
107+ WS -> RS;
108+ BS -> BIORXIV_WEB;
109+ MS -> MEDRXIV_WEB;
110+ RS -> REDALYC_WEB;
111+ EUPMC -> EUPMC_API;
112+ ARXIV -> ARXIV_API;
113+ CROSSREF -> CROSSREF_API;
114+ OPENALEX -> OPENALEX_API;
115+ PARSER -> FS_STORAGE;
116+ CONVERTER -> FS_STORAGE;
117+ VALIDATOR -> DB;
118+ }
0 commit comments