8000 GitHub - valtterisa/haalarikone-fi: Find what student studies based on their overall color(s). · GitHub
[go: up one dir, main page]

Skip to content

About

Find what student studies based on their overall color(s).

Resources

Contributing

Stars

5 stars

Watchers

1 watching

Forks

Latest commit

 

History

319 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Haalarikone

Finland's easiest overall database – a unique way to explore Finnish student culture through colors.

Find out what color overall a student in a specific field wears.

Overview

  • What it does:
    It helps you identify students' fields based on their signature overall colors.

  • Explore culture:
    Discover and learn about the colorful traditions of Finnish student life.

Live Site and Analytics

Check out the live project at: haalarikone.fi

Live analytics: https://app.databuddy.cc/public/Uu3N9TuBuUAa3wAS4pHNw

Tech Stack

  • Framework: Next.js 15 (App Router) with React 18
  • Language: TypeScript
  • Styling: Tailwind CSS with Radix UI components (Shadcn/ui)
  • Internationalization: next-intl (Finnish, English, Swedish)
  • Search: Deterministic in-memory filtering + fuzzy ranking, with AI fallback only on zero-result deterministic queries
  • Search logging: Turso (libSQL) + Drizzle ORM
  • AI/ML: Vercel AI SDK with Anthropic Claude 3 Haiku (zero-result fallback only)
  • Feedback: Discord webhook
  • Analytics: Databuddy
  • Testing: Vitest only — search API + advanced filters against real data/overall_data.json; CI on non-draft PRs
  • Package Manager: pnpm
  • Deployment: Vercel

Quick Links

Project Structure

student-overall-app/
├── app/                    # Next.js App Router pages
│   ├── [locale]/          # Localized routes (fi, en, sv)
│   │   ├── ala/           # Field pages
│   │   ├── alue/          # Area pages
│   │   ├── blog/          # Blog posts
│   │   ├── haalari/       # Overall detail pages
│   │   ├── oppilaitos/    # University pages
│   │   ├── vari/          # Color pages
│   │   └── page.tsx       # Home page
│   ├── api/               # API routes (search)
├── components/            # React components
│   ├── ui/                # Reusable UI components (Radix UI)
│   ├── search-container.tsx  # Home/hub search
│   ├── language-switcher.tsx  # i18n language switcher
│   ├── theme-switcher.tsx # Dark/light mode toggle
│   └── ...                # Feature components
├── content/               # Blog post content (JSON)
├── data/                  # Static data files
├── i18n/                  # Internationalization config
│   ├── routing.ts         # Route configuration
│   └── request.ts         # Request locale handling
├── lib/                   # Utility functions and helpers
│   ├── route-translations.ts  # Route segment translations
│   ├── slug-translations.ts   # Entity slug translations
│   ├── translate-path-client.ts  # Client-side path translation
│   ├── build-search-response.ts # Deterministic in-memory fuzzy search
│   ├── university-filters.ts   # Advanced filter matching (shared UI/API)
│   ├── query-understanding.ts  # AI fallback query parsing
│   ├── load-color-data.ts      # Dynamic color data from JSON
│   └── ...                # Other utilities
├── messages/              # Translation files (fi.json, en.json, sv.json)
├── types/                 # TypeScript type definitions
└── utils/                 # Utility functions

Features

  • Multi-language Support: Finnish (default), English, and Swedish
  • Deterministic Search: In-memory fuzzy search with exact color/filter matching
  • Route Translation: Automatic translation of route segments and slugs
  • Blog System: Static blog posts with multi-language support
  • Theme Support: Dark and light mode
  • Responsive Design: Mobile-first approach with Tailwind CSS
  • SEO Optimized: Dynamic metadata, sitemap, and structured data

Search Architecture

The search system is deterministic-first and fully in-memory by default. Text search filters against local university and color data, then ranks candidates with Fuse fuzzy search. Advanced filters (color / area / field / school) are applied client-side via shared matching in lib/university-filters.ts. AI parsing is used only if deterministic text search returns 0 results.

How It Works

flowchart TD
    A[User Query] --> B[Load In-Memory Data]
    B --> C[Build Deterministic Filters]
    C --> D[Apply Deterministic Filtering]
    D --> E[Rank with Fuzzy Search]
    E --> F{Any Results?}
    F -->|Yes| G[Return Deterministic Results]
    F -->|No| H[AI Query Understanding Fallback]
    H --> I[Re-run Deterministic Filtering + Ranking]
    I --> J[Return Fallback Results]
Loading

Search Flow

  1. Deterministic Query Interpretation

    • Extracts likely filters (color, area, school, field, organization) from the query using local in-memory values.
    • Detects color aliases directly from color metadata loaded from local data files.
  2. Deterministic Filtering

    • Applies all extracted filters over the local dataset in memory.
    • Includes color-base matching and organization/slug matching.
    • Uses a field-relaxation fallback only when organization + field combination would otherwise produce no results.
  3. Fuzzy Ranking

    • Ranks filtered candidates with Fuse.js.
    • Prioritizes exact organization/slug token matches before fuzzy tie-breaking.
    • Includes color text fields in fuzzy keys so color wording contributes to ranking quality.
  4. Color Variant Equivalence

    • Color singular/plural and common aliases are treated as equivalent in fuzzy matching.
    • Examples (all base colors): valkoinen ↔ valkoiset, musta ↔ mustat, punainen ↔ punaiset, sininen ↔ siniset, vihreä ↔ vihreät, keltainen ↔ keltaiset, oranssi ↔ oranssit, violetti ↔ violetit, pinkki ↔ pinkit, harmaa ↔ harmaat, ruskea ↔ ruskeat, turkoosi ↔ turkoosit.
  5. AI Fallback (Only On Miss)

    • If deterministic search returns zero results, API route calls AI query understanding and retries deterministic filtering/ranking.
    • This keeps AI usage low while preserving recovery for ambiguous or noisy queries.

Key Benefits

  • Lower Cost: Most queries are resolved without AI calls.
  • Predictable Results: One deterministic pipeline handles normal search traffic.
  • Natural Color Queries: Finnish singular/plural color forms match reliably.
  • Fast Runtime: Local in-memory filtering + fuzzy ranking avoids network/model latency on common paths.

Search query logging (Turso)

Completed search intents are stored in Turso (libSQL) via Drizzle. Each row is a full criteria snapshot: text query plus optional advanced filters.

Env vars (local .env / .env.local, and Cloudflare Worker secrets):

  • TURSO_DATABASE_URL — Turso database URL
  • TURSO_AUTH_TOKEN — Turso auth token
# apply schema to Turso
pnpm db:push

# Cloudflare production secrets
npx wrangler secret put TURSO_DATABASE_URL
npx wrangler secret put TURSO_AUTH_TOKEN

Logging runs server-side inside POST /api/search (fire-and-forget insert). Missing env or insert failures are silent and never affect search UX.

Testing

Primary suite is Vitest (search + filters + search-log). Turso pipeline + Playwright search-log are local-only (same TURSO_* as the app; skip if unset; not in CI).

Suite Role
app/api/search/route.test.ts Text search API integration (AI mocked)
lib/university-filters.test.ts Advanced filters (+ text ∩ filters)
lib/reconcile-field-organization.test.ts Guild vs field reconcile unit tests
lib/log-search-pipeline.test.ts Local: insertSearchLog → Turso
e2e/search-log.spec.ts Local Playwright: settled search → Turso
pnpm test
pnpm test:watch
pnpm test:e2e   # local; needs TURSO_* + Chromium (`pnpm exec playwright install chromium`)

Full policy: CONTRIBUTING.md.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines on how to contribute to this project.

Contact

For any questions or feedback, feel free to reach out:

License

See LICENSE file for details.


Made by @valtterisa

About

Find what student studies based on their overall color(s).

Resources

Contributing

Stars

5 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages

0