-
Notifications
You must be signed in to change notification settings - Fork 106
Add scholarship finder to Tiny Fish cookbook #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| VITE_SUPABASE_PROJECT_ID="ikudbmsjgzirpyjagdgm" | ||
| VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImlrdWRibXNqZ3ppcnB5amFnZGdtIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Njg5NjY5ODAsImV4cCI6MjA4NDU0Mjk4MH0.pjgHkm5fniTp0Dovn4U46VCPztrYBXjWxHEaLsLP5j0" | ||
| VITE_SUPABASE_URL="https://ikudbmsjgzirpyjagdgm.supabase.co" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||||||||||||||||||||
| # Logs | ||||||||||||||||||||||||||||
| logs | ||||||||||||||||||||||||||||
| *.log | ||||||||||||||||||||||||||||
| npm-debug.log* | ||||||||||||||||||||||||||||
| yarn-debug.log* | ||||||||||||||||||||||||||||
| yarn-error.log* | ||||||||||||||||||||||||||||
| pnpm-debug.log* | ||||||||||||||||||||||||||||
| lerna-debug.log* | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| node_modules | ||||||||||||||||||||||||||||
| dist | ||||||||||||||||||||||||||||
| dist-ssr | ||||||||||||||||||||||||||||
| *.local | ||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add .env patterns to prevent credential leakage. Environment files containing sensitive credentials (Supabase API keys, etc.) are not ignored. This creates a risk that developers could accidentally commit secrets to the repository. 🔒 Proposed fix to add environment file patterns📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # Editor directories and files | ||||||||||||||||||||||||||||
| .vscode/* | ||||||||||||||||||||||||||||
| !.vscode/extensions.json | ||||||||||||||||||||||||||||
| .idea | ||||||||||||||||||||||||||||
| .DS_Store | ||||||||||||||||||||||||||||
| *.suo | ||||||||||||||||||||||||||||
| *.ntvs* | ||||||||||||||||||||||||||||
| *.njsproj | ||||||||||||||||||||||||||||
| *.sln | ||||||||||||||||||||||||||||
| *.sw? | ||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| # Project Title - Scholarship Match Engine | ||
|
|
||
| **Live Link:** https://tinyfishscholarshipfinder.lovable.app/ | ||
|
|
||
| ## What This Project Is - | ||
| This project is an AI-powered scholarship discovery and comparison system that automatically finds, scans, and extracts scholarship information directly from official scholarship websites worldwide. | ||
|
|
||
| Instead of relying on outdated databases, PDFs, or manual searches, the system pulls live, up-to-date data from source websites and returns it in a clean, structured, and comparable format. Users can search scholarships based on financial need, country/region, academic level, or target university. | ||
|
|
||
| ## How it works | ||
| The system first uses an AI layer to identify and curate relevant scholarship websites based on user input such as: | ||
|
|
||
| Country or region | ||
|
|
||
| University or institution | ||
|
|
||
| Financial need / merit-based criteria | ||
|
|
||
| Academic level (undergraduate, postgraduate, PhD) | ||
|
|
||
| Field of study | ||
|
|
||
| This ensures that only official and relevant sources are used. | ||
|
|
||
|
|
||
| ## What to Expect | ||
| Live, up-to-date data pulled directly from official websites | ||
|
|
||
| Parallel web scanning for fast results | ||
|
|
||
| Real-time status updates during execution | ||
|
|
||
| Structured, comparable output (JSON) | ||
|
|
||
| **Demo Video** - https://drive.google.com/file/d/1GXZhJOjiVUP5XcGvTAvRGcYhTWoKXlsE/view?usp=sharing | ||
|
|
||
| ## Code snippet - | ||
| ```bash | ||
| const response = await fetch("https://mino.ai/v1/automation/run-sse", { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| "X-API-Key": "sk-mino-YOUR_API_KEY", | ||
| }, | ||
| body: JSON.stringify({ | ||
| url: "https://www.gebiz.gov.sg", | ||
| goal: "Extract the latest open government tenders. Return JSON with tenderTitle, agency, tenderID, procurementCategory, submissionDeadline, eligibilityCriteria, estimatedValue, tenderStatus, and tenderLink.", | ||
| browser_profile: "lite", | ||
| }), | ||
| }); | ||
|
|
||
| const reader = response.body!.getReader(); | ||
| const decoder = new TextDecoder(); | ||
|
|
||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) break; | ||
|
|
||
| const chunk = decoder.decode(value); | ||
| for (const line of chunk.split("\n")) { | ||
| if (line.startsWith("data: ")) { | ||
| const data = JSON.parse(line.slice(6)); | ||
|
|
||
| // Live browser view | ||
| if (data.streamingUrl) { | ||
| console.log("Live view:", data.streamingUrl); | ||
| } | ||
|
|
||
| // Final structured output | ||
| if (data.type === "COMPLETE" && data.resultJson) { | ||
| console.log("Extracted tenders:", data.resultJson); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
| ## Tech Stack | ||
|
|
||
| Next.js (TypeScript) | ||
|
|
||
| Mino API | ||
|
|
||
| AI | ||
|
|
||
| ## Architecture Diagram - | ||
| ```mermaid | ||
| flowchart TB | ||
|
|
||
| %% ======================= | ||
| %% UI LAYER | ||
| %% ======================= | ||
| UI["USER INTERFACE<br/>(React + Tailwind + Dashboard)"] | ||
|
|
||
| %% ======================= | ||
| %% INPUT & ORCHESTRATION | ||
| %% ======================= | ||
| ORCH["Search Orchestration Layer<br/>(Next.js API / Server Actions)"] | ||
|
|
||
| %% ======================= | ||
| %% INTELLIGENCE LAYER | ||
| %% ======================= | ||
| LLM["LLM Intelligence Layer<br/>(ChatGPT API / Gemini API)"] | ||
|
|
||
| %% ======================= | ||
| %% AUTOMATION LAYER | ||
| %% ======================= | ||
| MINO["MINO Web Automation<br/>(Scholarship Discovery & Extraction)"] | ||
|
|
||
| %% ======================= | ||
| %% DATA LAYER | ||
| %% ======================= | ||
| DB["DATA STORE<br/>(Supabase / Postgres)"] | ||
|
|
||
| %% ======================= | ||
| %% DETAIL NODES | ||
| %% ======================= | ||
| LLMD["• Interpret user intent<br/>• Region / University filtering<br/>• Generate authoritative scholarship links"] | ||
| MINOD["• Visit scholarship websites<br/>• Extract visible scholarship details<br/>• SSE streaming of results"] | ||
| DBD["• Cached scholarships<br/>• Deduplicated entries<br/>• Saved comparisons"] | ||
|
|
||
| %% ======================= | ||
| %% CONNECTIONS | ||
| %% ======================= | ||
| UI --> ORCH | ||
|
|
||
| ORCH --> LLM | ||
| LLM --> LLMD | ||
|
|
||
| ORCH --> MINO | ||
| MINO --> MINOD | ||
|
|
||
| ORCH --> DB | ||
| DB --> DBD | ||
|
|
||
| MINO --> ORCH | ||
| DB --> ORCH | ||
|
|
||
| ORCH --> UI | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "$schema": "https://ui.shadcn.com/schema.json", | ||
| "style": "default", | ||
| "rsc": false, | ||
| "tsx": true, | ||
| "tailwind": { | ||
| "config": "tailwind.config.ts", | ||
| "css": "src/index.css", | ||
| "baseColor": "slate", | ||
| "cssVariables": true, | ||
| "prefix": "" | ||
| }, | ||
| "aliases": { | ||
| "components": "@/components", | ||
| "utils": "@/lib/utils", | ||
| "ui": "@/components/ui", | ||
| "lib": "@/lib", | ||
| "hooks": "@/hooks" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import js from "@eslint/js"; | ||
| import globals from "globals"; | ||
| import reactHooks from "eslint-plugin-react-hooks"; | ||
| import reactRefresh from "eslint-plugin-react-refresh"; | ||
| import tseslint from "typescript-eslint"; | ||
|
|
||
| export default tseslint.config( | ||
| { ignores: ["dist"] }, | ||
| { | ||
| extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||
| files: ["**/*.{ts,tsx}"], | ||
| languageOptions: { | ||
| ecmaVersion: 2020, | ||
| globals: globals.browser, | ||
| }, | ||
|
Comment on lines
+11
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 92 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 1019 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 1012 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 55 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 1324 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 55 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 120 🏁 Script executed: Repository: tinyfish-io/tinyfish-cookbook Length of output: 732 Add ESLint override with Deno globals for serverless functions. The config applies to all Suggested override🤖 Prompt for AI Agents |
||
| plugins: { | ||
| "react-hooks": reactHooks, | ||
| "react-refresh": reactRefresh, | ||
| }, | ||
| rules: { | ||
| ...reactHooks.configs.recommended.rules, | ||
| "react-refresh/only-export-components": ["warn", { allowConstantExport: true }], | ||
| "@typescript-eslint/no-unused-vars": "off", | ||
| }, | ||
| }, | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <!-- TODO: Set the document title to the name of your application --> | ||
| <title>Lovable App</title> | ||
| <meta name="description" content="Lovable Generated Project" /> | ||
| <meta name="author" content="Lovable" /> | ||
|
|
||
| <!-- TODO: Update og:title to match your application name --> | ||
| <meta property="og:title" content="Lovable App" /> | ||
| <meta property="og:description" content="Lovable Generated Project" /> | ||
| <meta property="og:type" content="website" /> | ||
| <meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" /> | ||
|
|
||
| <meta name="twitter:card" content="summary_large_image" /> | ||
| <meta name="twitter:site" content="@Lovable" /> | ||
| <meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" /> | ||
| </head> | ||
|
|
||
| <body> | ||
| <div id="root"></div> | ||
| <script type="module" src="/src/main.tsx"></script> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not commit
.envfiles with real credentials to version control.This file contains actual Supabase credentials and should not be committed. While the
anonkey is designed to be public (it's embedded in client-side code), committing.envfiles sets a dangerous precedent and can lead to accidental exposure of sensitive secrets in the future.Additionally, the values should not be quoted in
.envfiles per dotenv conventions.Recommended approach:
.envto.gitignore.env.examplewith placeholder values for documentation📁 Proposed .env.example
Also add to
.gitignore:🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 1-1: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 2-2: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 3-3: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
🪛 Gitleaks (8.30.0)
[high] 2-2: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.
(jwt)
🤖 Prompt for AI Agents