<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andriyanto</title>
    <description>The latest articles on DEV Community by Andriyanto (@yandri918).</description>
    <link>https://dev.to/yandri918</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2740027%2F3a8b6c9e-1de2-4014-b6d4-a2d593e36e6a.png</url>
      <title>DEV Community: Andriyanto</title>
      <link>https://dev.to/yandri918</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yandri918"/>
    <language>en</language>
    <item>
      <title>AcademAI — An Open-Source Research Companion Built for My Wife's PAUD Thesis</title>
      <dc:creator>Andriyanto</dc:creator>
      <pubDate>Fri, 02 Oct 2026 11:45:09 +0000</pubDate>
      <link>https://dev.to/yandri918/academai-i-built-an-open-source-multi-disciplinary-academic-co-pilot-for-my-wife-and-every-elj</link>
      <guid>https://dev.to/yandri918/academai-i-built-an-open-source-multi-disciplinary-academic-co-pilot-for-my-wife-and-every-elj</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;AcademAI&lt;/strong&gt; for someone very close to my heart: &lt;strong&gt;my wife&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;She is currently completing her undergraduate thesis in &lt;strong&gt;S1 PAUD (Pendidikan Anak Usia Dini — Early Childhood Education)&lt;/strong&gt; in Indonesia while also managing our home and daily family life. Her research investigates how natural loose-parts media affects fine motor development in children aged 5–6 years.&lt;/p&gt;

&lt;p&gt;Every evening, I would sit beside her at our kitchen table and watch the real, human friction of academic research:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Fear of Fabricated Sources&lt;/strong&gt;: General AI assistants frequently invent scientific literature. When she asked for early childhood learning frameworks, chatbots confidently generated non-existent papers attributed to Jean Piaget, Lev Vygotsky, and Maria Montessori.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disconnection from Local Curriculum Standards&lt;/strong&gt;: Global AI models have no working knowledge of Indonesian statutory early childhood frameworks, particularly &lt;strong&gt;STPPA (Permendikbudristek No. 5/2022)&lt;/strong&gt; or the national developmental rubrics (&lt;strong&gt;BB&lt;/strong&gt; = &lt;em&gt;Belum Berkembang&lt;/em&gt;, &lt;strong&gt;MB&lt;/strong&gt; = &lt;em&gt;Mulai Berkembang&lt;/em&gt;, &lt;strong&gt;BSH&lt;/strong&gt; = &lt;em&gt;Berkembang Sesuai Harapan&lt;/em&gt;, &lt;strong&gt;BSB&lt;/strong&gt; = &lt;em&gt;Berkembang Sangat Baik&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translating Classroom Statistics into Academic Prose&lt;/strong&gt;: In her Classroom Action Research (PTK — &lt;em&gt;Penelitian Tindakan Kelas&lt;/em&gt;), computing paired sample t-tests and Hake's Normalized Gain (&lt;strong&gt;N-Gain&lt;/strong&gt;), then articulating what those numbers actually mean in formal Indonesian academic prose for Chapter IV (Bab IV), was a constant bottleneck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drafting Anxiety and Revision Fatigue&lt;/strong&gt;: Staring at a blank document trying to structure an inverted-pyramid background (&lt;em&gt;Latar Belakang&lt;/em&gt;) while juggling household duties drained her energy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What AcademAI Does
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AcademAI&lt;/strong&gt; is an open-source research companion designed to keep the student firmly in control while removing mechanical roadblocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traceable Literature Search via SerpApi&lt;/strong&gt;: Searches Google Scholar in real time for genuine, peer-reviewed articles and supplies verified titles, authors, and links so the student can inspect the original text before citing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Citation Format &amp;amp; Metadata Inspection&lt;/strong&gt;: Audits in-text citations (APA 7th) and DOI identifiers against retrieved paper metadata to help students catch misattributed quotes or missing publication years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PTK Statistics &amp;amp; Interpretation&lt;/strong&gt;: Takes raw pretest and posttest developmental assessment scores, calculates Paired Sample t-Tests and Hake (1999) N-Gain categories (&lt;code&gt;Tinggi&lt;/code&gt;, &lt;code&gt;Sedang&lt;/code&gt;, &lt;code&gt;Rendah&lt;/code&gt;), and generates a transparent narrative draft explaining the pedagogical implications for Bab IV.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Academic Restructuring &amp;amp; Paraphrasing&lt;/strong&gt;: Provides syntactic transformations (such as nominalization and formal impersonal passive voice) to help students convey their own arguments clearly and maintain formal academic tone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular Knowledge Framework&lt;/strong&gt;: Built and tested primarily around my wife's PAUD research, with an extensible &lt;strong&gt;DISCIPLINES Registry&lt;/strong&gt; that provides foundational theory templates for 11 other faculties (Education, Economics, Law, Health, Computer Science, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Having an assistant that actually finds real Indonesian journals and explains what my pretest-posttest N-Gain scores mean in proper academic wording saved me hours of second-guessing at night."&lt;/em&gt;&lt;br&gt;&lt;br&gt;
— &lt;strong&gt;My wife&lt;/strong&gt;, testing the first working draft of AcademAI.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Live Web Application&lt;/strong&gt;: &lt;a href="https://academicai-production-a41d.up.railway.app" rel="noopener noreferrer"&gt;https://academicai-production-a41d.up.railway.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;Live Health Endpoint&lt;/strong&gt;: &lt;a href="https://academicai-production-a41d.up.railway.app/healthz" rel="noopener noreferrer"&gt;https://academicai-production-a41d.up.railway.app/healthz&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Five-Step Research Flow (Demonstrated in Early Childhood Education)
&lt;/h3&gt;

&lt;p&gt;To see how the application works in practice, follow this real research flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Step 1: Enter Topic &amp;amp; Friction Point (Tab 1 — Chat)&lt;/strong&gt;
Select &lt;strong&gt;Pendidikan Anak Usia Dini (PAUD)&lt;/strong&gt;. Enter the research question: &lt;em&gt;"Bagaimana pemanfaatan media loose parts berbasis alam untuk menstimulasi motorik halus anak usia 5-6 tahun?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2: Inspect Traceable Literature&lt;/strong&gt;
AcademAI queries Google Scholar via &lt;strong&gt;SerpApi&lt;/strong&gt;. Before answering, it lists the discovered peer-reviewed articles with direct links, authors, and publication years so the user can verify them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3: Analyze Classroom Data (Tab 5 — Statistics)&lt;/strong&gt;
Enter classroom action research scores (e.g., Pretest: &lt;code&gt;[50, 55, 60, 52, 58]&lt;/code&gt;, Posttest: &lt;code&gt;[78, 85, 82, 80, 88]&lt;/code&gt;, Max Score: &lt;code&gt;100&lt;/code&gt;). AcademAI computes the mean difference, t-statistic, and Hake N-Gain (e.g., &lt;code&gt;0.58&lt;/code&gt; — Category &lt;em&gt;Sedang&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 4: Draft Empirical Discussion (Bab IV)&lt;/strong&gt;
The system generates an initial academic discussion linking the statistical gains back to Piaget's sensorimotor/pre-operational theory and the STPPA motor milestones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 5: Review &amp;amp; Export to Word (Tab 2 / DOCX Export)&lt;/strong&gt;
The student reviews, refines, and exports the formatted document as a &lt;code&gt;.docx&lt;/code&gt; file for offline editing and thesis advisor review.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify the live production deployment&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://academicai-production-a41d.up.railway.app/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AcademAI Universal Academic Engine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discipline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Universal Academic Research (Multi-Disciplinary)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"features"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"memory_context"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"pdf_parser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"plagiarism_checker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"google_scholar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"zotero_sync"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"full_generator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"citation_validator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"academic_stats"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"dataviz_mcp"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"models"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.1-flash-lite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.5-flash-lite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.7-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.8-flash"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yandri918" rel="noopener noreferrer"&gt;
        yandri918
      &lt;/a&gt; / &lt;a href="https://github.com/yandri918/academic_ai" rel="noopener noreferrer"&gt;
        academic_ai
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🎓 AcademAI — An Open-Source Research Companion Built for My Wife's PAUD Thesis&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://nodejs.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f61d630835f39758f5a2e68c7f85fae1b1fd14682ad6c2a1ab9884f277dc54bd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334432302e302e302d627269676874677265656e2e737667" alt="Node.js Version"&gt;&lt;/a&gt;
&lt;a href="https://academicai-production-a41d.up.railway.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8b0b1c590b7e5b921153624804bf0b044f2abc5021c97adb4b94f49ff9a01a54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f64656d6f2d6f6e6c696e652d626c75652e737667" alt="Live Demo"&gt;&lt;/a&gt;
&lt;a href="https://academicai-production-a41d.up.railway.app/healthz" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b4614d987c99d4eda0557ab34d996f2dfe3995500feb4b75542deb8701cfd427/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6865616c74682d3230302532304f4b2d737563636573732e737667" alt="Health Status"&gt;&lt;/a&gt;
&lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4ad4cae1351ea8cff661c208f4b32e817a05a2cad93debd0597e568a4b91a7c2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b746f626572666573742d323032362532305375626d697373696f6e2d6f72616e67652e737667" alt="Hacktoberfest 2026"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🎃 &lt;strong&gt;Submission for &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01" rel="nofollow"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Dedicated to&lt;/strong&gt;: Helping my wife complete her undergraduate thesis in Early Childhood Education (S1 PAUD), powered by an open-source Node.js agent harness, &lt;strong&gt;Google Gemini&lt;/strong&gt;, and &lt;strong&gt;SerpApi&lt;/strong&gt; for grounded literature search.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌐 Live Web Application&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Production URL&lt;/strong&gt;: &lt;a href="https://academicai-production-a41d.up.railway.app" rel="nofollow noopener noreferrer"&gt;https://academicai-production-a41d.up.railway.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Check Endpoint&lt;/strong&gt;: &lt;a href="https://academicai-production-a41d.up.railway.app/healthz" rel="nofollow noopener noreferrer"&gt;https://academicai-production-a41d.up.railway.app/healthz&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;💡 The Story Behind AcademAI&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Every evening, I watched my wife sit at our kitchen table overwhelmed by the friction of writing her undergraduate thesis in Early Childhood Education (S1 PAUD). Standard commercial AI tools:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fabricated academic sources&lt;/strong&gt; (inventing fake citations attributed to Piaget, Vygotsky, or Montessori).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knew nothing about local education standards&lt;/strong&gt; like Indonesia's &lt;strong&gt;STPPA (Permendikbudristek No. 5/2022)&lt;/strong&gt; or national developmental rubrics (&lt;strong&gt;BB / MB / BSH / BSB&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Left her stuck on empirical calculations&lt;/strong&gt; like Paired Sample…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/yandri918/academic_ai" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  High-Level System Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│     Client Layer: Vanilla HTML5 · CSS3 · ES2022 (Zero Build)     │
│   5 Research Tabs: Chat · Generator · Validator · Audit · Stats  │
└────────────────────────────────┬────────────────────────────────┘
                                 │ REST API
┌────────────────────────────────▼────────────────────────────────┐
│      OPEN-SOURCE AGENT HARNESS (Standalone Node.js / Express)   │
│                                                                 │
│   ┌────────────────────────────────────────────────────────┐    │
│   │  DISCIPLINES Registry (PAUD Focused + 11 Frameworks)   │    │
│   │  Canonical Theories · Pedagogical Rubrics (BB/MB/BSH)  │    │
│   └────────────────────────────┬───────────────────────────┘    │
│                                │                                │
│        ┌───────────────────────┼────────────────────────┐       │
│        ▼                       ▼                        ▼       │
│ ┌────────────────┐    ┌─────────────────┐      ┌──────────────┐ │
│ │ Google Gemini  │    │ SerpApi Engine  │      │ Zotero REST  │ │
│ │ 4-Model Chain  │    │ Google Scholar  │      │ Reference    │ │
│ │ Fallback Logic │    │ Live Index      │      │ Sync         │ │
│ └────────────────┘    └─────────────────┘      └──────────────┘ │
│                                                                 │
│ ┌─────────────────────────────┐   ┌───────────────────────────┐ │
│ │ Pure-JS Statistics Engine   │   │ RegEx Citation Validator  │ │
│ │ Paired t-Test · Hake N-Gain │   │ APA7 / CrossRef Checker   │ │
│ └─────────────────────────────┘   └───────────────────────────┘ │
│                                                                 │
│ ┌─────────────────────────────┐   ┌───────────────────────────┐ │
│ │ Persistent Document Memory  │   │ DOCX Academic Exporter    │ │
│ │ Local JSON Session Storage  │   │ Formatted Word Packaging  │ │
│ └─────────────────────────────┘   └───────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
             Deployed via Dockerfile → Railway Cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core Code Snippet 1: Grounded Literature Retrieval with SerpApi
&lt;/h3&gt;

&lt;p&gt;To ensure every factual claim has an inspectable source, &lt;code&gt;server.js&lt;/code&gt; queries Google Scholar via SerpApi before composing the prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js (MIT Licensed)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;searchGoogleScholar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serpApiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SERPAPI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;serpApiKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[Scholar] No SerpApi key provided, continuing without live search.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://serpapi.com/search.json?engine=google_scholar&amp;amp;q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;api_key=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;serpApiKey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;hl=id&amp;amp;num=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`SerpApi returned status &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;organic_results&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Untitled Academic Paper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publication_info&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;snippet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;snippet&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;citations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inline_links&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;cited_by&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publication_info&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b(&lt;/span&gt;&lt;span class="sr"&gt;20&lt;/span&gt;&lt;span class="se"&gt;\d{2}&lt;/span&gt;&lt;span class="sr"&gt;|19&lt;/span&gt;&lt;span class="se"&gt;\d{2})\b&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2023&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[SerpApi Error]:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Core Code Snippet 2: Transparent PTK Statistics Engine
&lt;/h3&gt;

&lt;p&gt;The statistical engine runs directly in Node.js using pure mathematics, ensuring full visibility into every step of the calculation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js — Transparent calculation of Paired t-Test and Hake (1999) Normalized Gain&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/stats/calculate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pretest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posttest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Perkembangan Motorik Halus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pretest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diffs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pretest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;posttest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meanDiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;diffs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;variance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;diffs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;meanDiff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;standardError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;variance&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tStat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;standardError&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;meanDiff&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;standardError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pretest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postAvg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posttest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nGain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxScore&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postAvg&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxScore&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nGainCategory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nGain&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tinggi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nGain&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sedang&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rendah&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tStat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tStat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;nGain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nGain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;nGainPercent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nGain&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;nGainCategory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;preAvg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;postAvg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;postAvg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;interpretation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;generateAcademicProse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;variableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tStat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nGain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nGainCategory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;preAvg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;postAvg&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The challenge explicitly accepts &lt;strong&gt;open-source agent harnesses&lt;/strong&gt; as a qualifying open-source AI foundation. AcademAI is built around a custom, lightweight &lt;strong&gt;Node.js/Express open-source agent harness&lt;/strong&gt; (&lt;code&gt;server.js&lt;/code&gt;, MIT Licensed), powered by &lt;strong&gt;Google Gemini&lt;/strong&gt; and grounded with &lt;strong&gt;SerpApi&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Open-Source Agent Harness (&lt;code&gt;server.js&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Instead of relying on heavy closed agent frameworks or bloated multi-container microservices, AcademAI is designed as an accessible, standalone open-source harness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Knowledge Engine&lt;/strong&gt;: Injects foundational theories (Piaget, Vygotsky, Montessori) and curriculum rubrics (STPPA, BB/MB/BSH/BSB) into the context based on user input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pure JavaScript Math&lt;/strong&gt;: Implements t-tests and Hake's N-gain without external proprietary statistical packages, ensuring transparency and repeatability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOCX Word Exporter&lt;/strong&gt;: Uses the open-source &lt;code&gt;docx&lt;/code&gt; library to compile structured thesis drafts into standard &lt;code&gt;.docx&lt;/code&gt; files for advisor review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session Memory&lt;/strong&gt;: Uses isolated session identifiers to persist research documents locally in &lt;code&gt;./data/memory.json&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Scholarly Grounding via SerpApi
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generic LLMs invent citations because they predict tokens without index verification.&lt;/li&gt;
&lt;li&gt;We integrate &lt;strong&gt;SerpApi&lt;/strong&gt; to query the live &lt;strong&gt;Google Scholar&lt;/strong&gt; index, fetching real publication titles, snippets, citation counts, and direct links.&lt;/li&gt;
&lt;li&gt;These verified references are injected into the agent prompt, drastically reducing the risk of phantom citations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. AI Inference: Google Gemini with 4-Model Fallback Chain
&lt;/h3&gt;

&lt;p&gt;We utilize &lt;strong&gt;Google Gemini&lt;/strong&gt; for its state-of-the-art academic prose and generous free tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a model encounters a rate limit or server load during peak hours, the harness automatically cascades through fallback tiers (&lt;code&gt;gemini-3.1-flash-lite&lt;/code&gt; → &lt;code&gt;gemini-3.5-flash-lite&lt;/code&gt; → &lt;code&gt;gemini-3.7-flash&lt;/code&gt; → &lt;code&gt;gemini-3.8-flash&lt;/code&gt;) so the student's late-night writing session is never abruptly halted.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Removing Financial Barriers for Developing World Students
&lt;/h3&gt;

&lt;p&gt;There are over &lt;strong&gt;8 million university students across Indonesia&lt;/strong&gt;. Most students in regional teacher-training colleges (&lt;em&gt;LPTK&lt;/em&gt;) study on budget laptops or mobile devices. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commercial AI tools charge &lt;strong&gt;$20 to $30 per month&lt;/strong&gt; — often equivalent to several weeks of a student's living budget in regional Indonesia.&lt;/li&gt;
&lt;li&gt;Open innovation — combining a lightweight MIT-licensed agent harness, accessible search APIs like &lt;strong&gt;SerpApi&lt;/strong&gt;, and Gemini's free tier — proves that state-of-the-art research support can be made freely accessible without subscription gatekeeping.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Transparent, Defendable Academic Rigor
&lt;/h3&gt;

&lt;p&gt;In a university thesis defence, a student cannot say: &lt;em&gt;"the AI told me this was true."&lt;/em&gt; They must defend their sources, explain their data, and verify their citations. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With open innovation, every algorithm in AcademAI is transparent.&lt;/li&gt;
&lt;li&gt;The student can inspect the exact mathematics of their t-test, click the direct link provided by SerpApi to verify a paper's existence, and inspect the prompt rules on GitHub. Open innovation preserves human agency and academic integrity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Self-Hostable and Customizable
&lt;/h3&gt;

&lt;p&gt;Because the application code is open-source (MIT), any university department or student union can clone the repository, customize the &lt;code&gt;DISCIPLINES&lt;/code&gt; registry to match their local faculty guidelines, and host it independently on their own infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;AcademAI was engineered with the assistance of &lt;strong&gt;Antigravity IDE&lt;/strong&gt; (Google DeepMind's agentic pair-programming system). &lt;/p&gt;

&lt;p&gt;Throughout the session, the agent and I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consolidated the prototype into a clean, standalone &lt;code&gt;server.js&lt;/code&gt; agent harness to eliminate container bloat and ensure fast cold starts.&lt;/li&gt;
&lt;li&gt;Connected SerpApi for live Google Scholar index querying and grounded literature injection.&lt;/li&gt;
&lt;li&gt;Built and verified the pure JavaScript statistical engine for Classroom Action Research (PTK) and Hake's N-Gain formulas.&lt;/li&gt;
&lt;li&gt;Configured Google Gemini with an automated 4-model fallback cascade.&lt;/li&gt;
&lt;li&gt;Packaged the application with Docker and verified the live cloud deployment on Railway with automated &lt;code&gt;/healthz&lt;/code&gt; monitoring.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of SerpApi&lt;/strong&gt;: AcademAI deeply integrates &lt;strong&gt;SerpApi&lt;/strong&gt; to query the live &lt;strong&gt;Google Scholar&lt;/strong&gt; index, grounding thesis writing in verified, peer-reviewed publications and providing students with traceable citation links.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hacktoberfest</category>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
