Skip to content

ElScelt/Palgaturu-Analyys-Eestis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Eesti Palgaturu Analüüsi Rakendus

Veebirakendus Eesti palgaturu andmete analüüsimiseks, kasutades Statistikaameti API-d ja OpenAI GPT-4 tehisintellekti.

Next.js TypeScript Tailwind CSS License


⚠️ Oluline Märkus: Andmete Perioodidest

Ülesandes paluti: "viimased viis aastat" Implementeeritud: 3 perioodi üle 8 aasta (2014, 2018, 2022)

Põhjendus: Statistikaameti uues andmebaasis (andmed.stat.ee) on saadaval PA6391 tabel (Täis- ja osalise tööajaga töötajate keskmine brutotunnitasu), mis pakub andmeid ISCO-08 ametialade (pearühmad) järgi. Tabel sisaldab oktoobri palgamõõtmisi perioodidega 2014, 2018, 2022.

Uurimistöö tulemus:

  • PA627 (Palgastruktuuriuuring) ❌ ei eksisteeri uues andmed.stat.ee süsteemis
  • PA6391 (Oktoobrikuu brutotunnitasu) ✅ Ainus saadaolev tabel ISCO-08 ametialade kohta
  • PA111-PA119 (Kvartaalsed andmed) ❌ Ainult tegevusalade järgi, mitte ametialade

Loogiline järeldus: PA6391 on parim ja ainus saadaolev andmestik ametialade kaupa uues Statistikaameti süsteemis. 3 andmepunkti 8 aasta jooksul annab selge ülevaate palgakasvu trendidest.

Täpsem tehniline analüüs, probleemilahendus ja API integratsioon on dokumenteeritud all pool sektsioonis "Tehnilised Lahendused ja Arhitektuur".


📋 Ülevaade

See rakendus võimaldab kasutajatel:

  • Valida ametinimetuse või valdkonna dropdownist (50+ ametit ISCO-08 klassifikaatori järgi)
  • Vaadata palgaajalugu perioodil 2014-2022 interaktiivsel graafikul (Statistikaameti päris andmed!)
  • Saada AI-põhist analüüsi palgaturu trendidest, prognoosidest ja karjäärisoovitustest

🎯 Tehnilised Lahendused ja Arhitektuur

Arhitektuuri Ülevaade

┌─────────────────────────────────────────────────────────┐
│                    Frontend (Next.js)                   │
│  ┌────────────┐  ┌────────────┐  ┌─────────────────┐  │
│  │ Occupation │  │   Salary   │  │   AI Analysis   │  │
│  │  Selector  │  │   Chart    │  │   Component     │  │
│  └────────────┘  └────────────┘  └─────────────────┘  │
└─────────┬──────────────────────────────────┬───────────┘
          │                                  │
          │ (client-side)                    │ (server-side)
          ▼                                  ▼
┌──────────────────┐              ┌──────────────────┐
│ Statistics Estonia│              │  /api/analyze    │
│   API (PA6391)   │              │  (Next.js API)   │
│  [Client-Side]   │              └────────┬─────────┘
└──────────────────┘                       │
                                           ▼
                                 ┌──────────────────┐
                                 │   OpenAI API     │
                                 │   (GPT-4 Turbo)  │
                                 └──────────────────┘

Märkus: Statistics Estonia API kutsutakse OTSE brauserist (client-side),
        kuna API blokeerib server-poolsed päringud.

Tehnilised Otsused ja Põhjendused

1. Next.js 16 Server-Side Architecture

Otsus: Kasutan Next.js App Router'it koos Server Components'iga.

Põhjendus:

  • SEO: Server-side rendering tagab, et sisu on indekseeritav otsingumootoritele
  • Performance: Initial page load on kiirem, sest HTML renderitakse serveris
  • API Routes: Built-in API endpoints ilma täiendavate serveriteta
  • Type Safety: TypeScript integratsioon on sujuv ja täielik

2. Statistikaameti API Integratsioon

Otsus: Kasutan PA6391 tabelit (Täis- ja osalise tööajaga töötajate keskmine brutotunnitasu) perioodidega 2014, 2018, 2022.

Põhjendus (Loogiline Mõtlemine):

Probleem: Ülesandes paluti "viimased 5 aastat", kuid Statistikaameti andmebaasis ei ole iga-aastaseid palgaandmeid ametialade järgi.

Uurimistöö Tulemused:

  1. PA627 - Palgastruktuuriuuring: ❌ Ei eksisteeri uues andmed.stat.ee süsteemis
  2. PA6391 - Oktoobrikuu brutotunnitasu ISCO-08 pearühmade järgi: ✅ 2014, 2018, 2022
  3. PA111-PA119 - Kvartaalsed andmed: ❌ Ainult tegevusalade järgi, mitte ametialade

Lõplik Lahendus:

  • PA6391 on ainus saadaolev tabel, mis pakub palgaandmeid ISCO-08 ametialade järgi uues süsteemis
  • Kasutab ISCO-08 pearühmi (major groups): OC1-OC9 (nt OC2 = Tippspetsialistid)
  • 3 andmepunkti: 2014, 2018, 2022 (oktoobri mõõtmised)
  • Andmed on haridustasemete (ED0-ED8) kaupa - arvutan keskmise üle kõigi haridustasemete

Probleemilahendus Arenduse Käigus:

  • Esialgselt püüdsin kasutada PA627 tabelit → 400 Bad Request (tabel ei eksisteeri)
  • Uurisin API metadata (GET /PA6391) → Leidsin õiged väljanimede
  • Implementeerisin korrektsed API päringud kõigi nõutud dimensioonidega

Tehnilised Detailid:

// PA6391 nõuab KÕIKI 5 dimensiooni
const requestBody = {
  query: [
    { code: "Näitaja", selection: { filter: "item", values: ["GR_H"] }},           // Brutotunnitasu
    { code: "Sugu", selection: { filter: "item", values: ["M_F"] }},               // Mehed ja naised
    { code: "Haridustase", selection: { filter: "item", values: ["ED0"..."ED8"] }}, // Kõik tasemed
    { code: "Ametiala pearühm", selection: { filter: "item", values: ["OC2"] }},   // ISCO-08 pearühm
    { code: "Vaatlusperiood", selection: { filter: "item", values: ["2014", "2018", "2022"] }}
  ],
  response: { format: "json" }
};

Andmete Transformatsioon:

// PA6391 tagastab andmed haridustasemete kaupa
// Näide: key = ["GR_H", "M_F", "ED6", "OC2", "2022"], values = ["13.71"]

// 1. Grupeeri andmed aastate kaupa
const yearMap = new Map<number, number[]>();
for (const item of apiData.data) {
  const year = parseInt(item.key[4]);        // Aasta on key[4]
  const hourlyWage = parseFloat(item.values[0]);
  if (item.values[0] !== '..' && !isNaN(hourlyWage)) {
    yearMap.get(year).push(hourlyWage);
  }
}

// 2. Arvuta keskmine tunnitasu iga aasta kohta (üle kõigi haridustasemete)
const avgHourlyWage = wages.reduce((sum, w) => sum + w, 0) / wages.length;

// 3. Teisenda kuupalgaks
const HOURS_PER_MONTH = 168; // 40h/nädal × 4.2 nädalat
const monthlyWage = Math.round(avgHourlyWage * HOURS_PER_MONTH);

// 4. Arvuta kasv
const growth = ((currentWage - previousWage) / previousWage * 100).toFixed(1);

⚠️ Oluline Tehniline Lahendus: Client-Side vs Server-Side API Päringud

Probleem Avastatud Arenduse Käigus: Esialgselt prooviti Statistikaameti API-t kutsuda serveri poolelt (Next.js API route /api/salary-data), kuid see tagastas "403 Access Denied" vea kõikidele päringutele.

Uurimistöö:

# Server-side päring (Next.js API route)
curl -X POST https://andmed.stat.ee/api/v1/et/stat/PA627
# Tulemus: "Access denied"

# Isegi API config ja manual on blokeeritud:
curl https://andmed.stat.ee/api/v1/en?config
# Tulemus: "Access denied"

Analüüs:

  • Statistikaameti API blokeerib päringud serverite/cloud IP-delt
  • See on tavaline turvameede, et vältida automatiseeritud skrapimist
  • API on mõeldud brauseri-poolseteks päringuteks (CORS lubatud brauseritele)

Lahendus: Tegin API päringu client-side (React komponendis), mitte server-side (API route'is):

// ❌ EI TÖÖTA: Server-side (Next.js API route)
// app/api/salary-data/route.ts
export async function POST() {
  const response = await fetch('https://andmed.stat.ee/...'); // Access denied
}

// ✅ TÖÖTAB: Client-side (React komponent)
// app/page.tsx
async function fetchSalaryDataFromStatisticsEstonia() {
  const response = await fetch('https://andmed.stat.ee/...'); // OK!
  // Päring tehakse kasutaja brauserist, mitte serverist
}

Arhitektuuri Muudatus:

ENNE:
Browser → Next.js API Route → Statistics Estonia API (❌ blocked)

PÄRAST:
Browser → Statistics Estonia API (✅ works!)
Browser → Next.js API Route → OpenAI API (✅ works - needs server-side for security)

Õppetund: Mõnikord on tehnilised piirangud väliste API-de poolel. Paindlik arhitektuur ja probleemlahendamisoskus on võtmetähtsusega. Client-side API päringud töötavad siin paremini, samas kui OpenAI API pääsuvõti peab jääma serverisse turvalisuse huvides.

3. OpenAI GPT-4 Integratsioon

⚠️ OLULINE MÄRKUS: OpenAI API testimine

OpenAI GPT-4 API integratsioon on täielikult implementeeritud ja valmis kasutamiseks, kuid seda ei ole tegelikult testitud OpenAI API võtmega, kuna võtme hankimiseks oleks vajalik $5 minimaalne sissemakse, mida pole hetkel võimalik teha.

Implementeeritud funktsionaalsus:

  • ✅ GPT-4 Turbo API integratsioon (OpenAI SDK 4.76.1)
  • ✅ Struktureeritud prompt engineering (3-osaline analüüs)
  • ✅ Error handling ja graceful degradation
  • ✅ Rate limiting ja võtme valideerimise kontroll
  • ✅ Kasutajasõbralik veateade kui võti puudub

Testimata jäänud:

  • ❌ Tegelik API vastus ja analüüsi kvaliteet
  • ❌ Token kulud ja vastuse pikkused
  • ❌ Rate limiting käitumine päris kasutuses

Alternatiivne testimisviis: Kui vaja, saab testimist teostada pärast API võtme saamist (nt palgapäeval 21. nov või pärast tööleasumist), lisades .env.local faili võtme ja käivitades rakenduse lokaalses.

Kood on siiski täielikult valmis ja järgib best practices'e, nagu näha app/api/analyze/route.ts failis.


Otsus: Kasutan GPT-4 Turbo Preview mudelit struktureeritud prompt'iga.

Põhjendus:

  • GPT-4 vs GPT-3.5: Parem faktilisuse ja konteksti mõistmise poolest (~30% parem)
  • Temperature: 0.7: Balanss faktilisuse (0.0) ja loovuse (1.0) vahel
  • Max Tokens: 1200: Piisav põhjalikuks analüüsiks (~400-600 sõna)
  • Struktureeritud Prompt: Tagab järjepideva kvaliteedi

Prompt Engineering:

// System Role: Määrab AI eksperdi rolli
{
  role: "system",
  content: "Sa oled ekspert tööturgu analüüsiv spetsialist..."
}

// User Prompt: 3-osaline struktuur
1. PALGATREND - Faktide analüüs (tõusev/langev/stabiilne)
2. PROGNOOS - 2-3 aastat (majandus, inflatsioon, tööjõu nõudlus)
3. SOOVITUSED - Konkreetsed sammud (oskused, läbirääkimised)

Error Handling:

// Graceful degradation
if (!process.env.OPENAI_API_KEY) {
  return "⚠️ AI analüüs ei ole saadaval: OpenAI API võti puudub"
}

// Rate limiting
if (error?.status === 429) {
  return "Liiga palju päringuid. Palun proovi hiljem uuesti."
}

4. Type Safety ja Andmestruktuurid

Otsus: Kasutan TypeScript interface'e kõikjal, kus andmed liiguvad.

// Kindel tüübikontroll
interface SalaryDataPoint {
  year: number;
  avgSalary: number;
  growth: number;
}

interface Occupation {
  code: string;        // ISCO-08 kood (nt "OC25")
  name: string;        // Ametinimetus eesti keeles
  category: string;    // Valdkond
}

Põhjendus:

  • Vältida runtime errored (95% vigadest tabatakse compile-time'is)
  • Parem IDE autocompletion ja dokumentatsioon
  • Lihtsamini hooldatav kood

5. UI/UX Optimisatsioonid

Responsive Design:

// Mobile-first lähenemine
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
  // 2 veergu mobiilis, 4 veergu desktopis
</div>

// Adaptive padding
<div className="px-4 sm:px-6 lg:px-8">
  // Suureneb ekraani kasvades
</div>

Loading States:

  • Spinner animatsioon andmete laadimise ajal
  • Disabled state dropdownidel laadimise ajal
  • Smooth transitions (fade-in animatsioonid)

Error Handling:

  • Selged, kasutajasõbralikud veateated
  • Punased error boxid (visuaalne eristumine)
  • Fallback kui OpenAI API puudub

🚀 Funktsionaalsus

1. Ametinimetuste Valik (50+ ametit)

  • 13 valdkonda: IT, Tervishoid, Haridus, Ehitus, Juhtimise, Rahandus, Õigus, Müük, Tootmine, Transport, Kunst, Muu
  • ISCO-08 klassifikaator: Rahvusvaheliselt tunnustatud ametite standard
  • Dünaamiline filtreerimine: Valdkonna valik filtreerib ametinimetusi reaalajas

2. Palgaandmete Visualiseerimine

  • Interaktiivne LineChart (Recharts library)
  • Custom Tooltip: Hover efekt detailse info saamiseks
  • 4 Statistika Kaarti:
    • 🔵 Alguspalk (2014)
    • 🟢 Praegune palk (2022)
    • 🟣 Kogukasv % (8 aasta jooksul)
    • 🟠 Keskmine aastane kasv %
  • Responsive: Kohandub automaatselt ekraani suurusele

3. AI Analüüs (GPT-4)

Analüüsi Struktuur:

  1. PALGATREND:

    • Kas palk on tõusmas/langemas/stabiilne
    • Peamised mõjutavad tegurid Eesti tööturul
  2. PROGNOOS (2-3 aastat):

    • Eesti majanduskasvu prognoosid
    • Inflatsiooni mõju (~5-10%)
    • Tööjõu nõudlus/pakkumine valdkonnas
    • Digitaliseerimise ja tehnoloogia mõju
  3. SOOVITUSED:

    • Palgatõusu läbirääkimiste aeg
    • Soovitatud oskused ja sertifikaadid
    • Seotud ametid kõrgema palgaga
    • Valdkonnavahetuse kaalutlused

🛠 Tehnoloogiad

Frontend

  • Next.js 16.0.1 - React framework App Router'iga
  • TypeScript 5.9.3 - Tüübiturvaline JavaScript
  • Tailwind CSS 3.4.18 - Utility-first CSS
  • Recharts 2.15.0 - Data visualization library

Backend / API

  • Next.js API Routes - Serverless endpoints
  • OpenAI SDK 4.76.1 - GPT-4 integratsioon
  • Axios 1.7.9 - HTTP klient

Development Tools

  • PostCSS - CSS transformatsioonid
  • Autoprefixer - CSS vendor prefiksid
  • ESLint - Kood kvaliteedi kontroll

📦 Paigaldamine

Eeltingimused

  • Node.js 18+ ja npm
  • OpenAI API võti (valikuline, kuid soovitatud)

Kiire Start

# 1. Klooni repositoorium
git clone https://github.com/[kasutajanimi]/palgaturu-analyys.git
cd palgaturu-analyys/palgaturu-analyys

# 2. Installi sõltuvused
npm install

# 3. [VALIKULINE] Seadista OpenAI API võti
echo "OPENAI_API_KEY=sk-proj-your-key-here" > .env.local

# 4. Käivita development server
npm run dev

# 5. Ava brauser: http://localhost:3000

🔧 Keskkonnamuutujad

Loo .env.local fail projekti juurkataloogis:

# OpenAI API Key (VALIKULINE - rakendus töötab ilma selleta!)
# Kui puudub, näidatakse AI analüüsi sektsioonis hoiatust
OPENAI_API_KEY=sk-proj-...

# Statistics Estonia API URL (valikuline, on vaikeväärtus)
NEXT_PUBLIC_STATS_API_URL=https://andmed.stat.ee/api/v1/et/stat

OpenAI API Võtme Hankimine

OLULINE: Rakendus töötab TÄIELIKULT ilma OpenAI API võtmeta!

  • Palgaandmed ja graafikud töötavad normaalselt ✅
  • AI analüüsi kohas kuvatakse informatsioon võtme puudumise kohta ⚠️

Kui soovid AI analüüsi testida:

  1. Mine: https://platform.openai.com/
  2. Logi sisse või loo konto
  3. Mine Settings → API keys
  4. Klõpsa "Create new secret key"
  5. Kopeeri võti ja lisa .env.local faili

Kulud:

  • GPT-4 Turbo: ~$0.01-0.03 analüüsi kohta
  • $5 krediit annab ~200-500 analüüsi
  • Esimese $5 eest saad piisavalt testimiseks

🚢 Deployment (Vercel)

Automated Deployment

  1. Push GitHub'i:
git push origin main
  1. Ühenda Vercel:
  • Mine: https://vercel.com
  • Klõpsa "Import Project"
  • Vali GitHub repositoorium
  • Vercel tuvastab automaatselt Next.js projekti
  1. Lisa keskkonnamuutujad:
  • Project Settings → Environment Variables
  • Lisa OPENAI_API_KEY (kui soovid AI-d kasutada)
  • Deploy → Valmis! ✅

Deployment URL: https://palgaturu-analyys.vercel.app


📁 Projekti Struktuur

palgaturu-analyys/
├── app/
│   ├── api/
│   │   ├── salary-data/
│   │   │   └── route.ts          # Statistikaameti API endpoint
│   │   └── analyze/
│   │       └── route.ts          # OpenAI GPT-4 API endpoint
│   ├── components/
│   │   ├── OccupationSelector.tsx # Dropdown selektor
│   │   ├── SalaryChart.tsx        # Recharts graafik
│   │   └── AIAnalysis.tsx         # AI analüüsi kuvamine
│   ├── globals.css                # Globaalsed stiilid + dropdown fix
│   ├── layout.tsx                 # Root layout + metadata
│   ├── page.tsx                   # Pealeht (main page)
│   └── icon.svg                   # Favicon (chart ikoon)
├── lib/
│   └── occupations.ts             # 50+ ametinimetust (ISCO-08)
├── .env.local                     # Keskkonna muutujad (GIT-i EI PANDA!)
├── .gitignore
├── next.config.js
├── package.json
├── tailwind.config.ts
├── tsconfig.json
└── README.md

🔐 Turvalisus

API Võtme Kaitse

// ✅ ÕIGE: Serveripoolne API call
// app/api/analyze/route.ts
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY, // Serveris, MITTE kliendis
});

// ❌ VALE: Ei tohi kunagi panna kliendipoolsesse koodi
const apiKey = "sk-proj-..."; // MITTE KUNAGI!

Turvalisuse Kontrollnimekiri:

  • .env.local on .gitignore's
  • ✅ API võti on ainult serveripoolses koodis
  • ✅ Vercel Environment Variables on krüpteeritud
  • ✅ Rate limiting on rakendatud API route'ides
  • ✅ Input validation (TypeScript interface'id)

🐛 Vigade Lahendamine

"OpenAI API võti ei ole konfigureeritud"

Lahendus:

# Kontrolli, et .env.local fail eksisteerib
ls -la .env.local

# Kontrolli faili sisu
cat .env.local

# Peaks sisaldama:
OPENAI_API_KEY=sk-proj-...

# Restart development server
npm run dev

"Statistikaameti API ei vastanud"

Võimalikud põhjused:

  1. Internetiühendus puudub
  2. Statistikaameti API on ajutiselt maas
  3. Vale ISCO-08 kood (nt "OC999" ei eksisteeri)

Lahendus:

# Testi API ühendust otse
curl -X POST https://andmed.stat.ee/api/v1/et/stat/PA6391 \
  -H "Content-Type: application/json" \
  -d '{"query":[{"code":"Näitaja","selection":{"filter":"item","values":["GR_H"]}}]}'

TypeScript Compilation Errors

Lahendus:

# Kontrolli tüüpe
npm run build

# Kui vajalik, uuenda sõltuvused
rm -rf node_modules package-lock.json
npm install

💡 Edasiarendused

Võimalikud täiustused:

  • Palgade võrdlus: Võrdle mitut ametit korraga
  • Maakondlikud andmed: Filtreerimine Harju, Tartu jne järgi
  • Soopõhine analüüs: Mehed vs naised palgavahed
  • PDF Export: Salvesta analüüs PDF-ina
  • Graafiku eksport: PNG/SVG download
  • Ajaloolised andmed: Laiendamine (15-20 aastat)
  • Kasutajaprofiilid: Salvestatud analüüsid
  • Email raportid: Saada analüüs emailile
  • Multi-language: Inglise, vene keel

📊 API Dokumentatsioon

POST /api/salary-data

Hangi palgaandmed Statistikaameti API-st.

Request:

{
  "occupationCode": "OC25",
  "occupationName": "IKT spetsialistid"
}

Response:

{
  "occupation": "IKT spetsialistid",
  "data": [
    { "year": 2014, "avgSalary": 1800, "growth": 0 },
    { "year": 2018, "avgSalary": 2200, "growth": 22.2 },
    { "year": 2022, "avgSalary": 2800, "growth": 27.3 }
  ],
  "source": "Statistikaamet (PA6391)",
  "note": "Andmed põhinevad oktoobri brutotunnitasul, konverteeritud kuupalgaks",
  "apiCode": "OC2"
}

Error Responses:

// 400 Bad Request
{ "error": "Ametinimetus on kohustuslik" }

// 503 Service Unavailable
{ "error": "Statistikaameti API ei vastanud" }

POST /api/analyze

Genereeri AI analüüs palgaandmete põhjal.

Request:

{
  "occupation": "IKT spetsialistid",
  "salaryData": [
    { "year": 2014, "avgSalary": 1800, "growth": 0 },
    { "year": 2018, "avgSalary": 2200, "growth": 22.2 },
    { "year": 2022, "avgSalary": 2800, "growth": 27.3 }
  ]
}

Response:

{
  "occupation": "IKT spetsialistid",
  "analysis": "PALGATREND:\nIKT spetsialistide palk on...",
  "timestamp": "2025-11-12T10:30:00.000Z"
}

Error Responses:

// 500 Internal Server Error (võti puudub)
{ "error": "OpenAI API võti ei ole konfigureeritud" }

// 401 Unauthorized (kehtetu võti)
{ "error": "OpenAI API võti on kehtetu" }

// 429 Too Many Requests
{ "error": "Liiga palju päringuid. Palun proovi hiljem uuesti" }

📄 Litsents

MIT License - vaba kasutamiseks ja muutmiseks.


🙏 Tänuavaldused

  • Statistikaamet - Palgaandmete allikas (PA6391 tabel)
  • OpenAI - GPT-4 AI mudel
  • Next.js / Vercel - Framework ja hosting
  • Recharts - Graafiku library
  • Tailwind Labs - CSS framework

Valmistatud: November 2025 Versioon: 1.0.0 Tehnoloogiad: Next.js 16, TypeScript 5.9, Tailwind CSS 3.4, OpenAI GPT-4 Turbo Autor: Edgar Raudsepp

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors