Tech Stack
Python + MySQL
Flask backend, Cron jobs, din befintliga VPS
Rutter att bevaka
5 × 5 = 25
Nordiska flygplatser → Thai destinationer
MVP-tid
2–3 veckor
Fas 1 live med deals + signup
1
Systemarkitektur
Cron Scheduler
Kör var 4-6:e timme.
25 rutter × 3 mån framåt
→
Flight Search API
Amadeus / Tequila
fly_from → fly_to
Priser i SEK
→
MySQL Database
Spara priser, beräkna
medelvärden, historik
→
Deal Detection
Pris < 60% av medel?
→ Flagga som DEAL
→
E-post / Sajt
Mailgun utskick +
uppdatera sajten
✅ Redan klart: VPS med CyberPanel + MySQL, subdomänen thaitrip.wenesthosting.com uppsatt med SSL, och landingpage deployad.
2
Filstruktur
thaitrip/
├── crawler/ # Prisbevakning
│ ├── flight_search.py # Flight API-klient
│ ├── deal_detector.py # Jämför mot historik, flagga deals
│ ├── routes.py # 25 rutter: ARN→BKK, CPH→HKT, etc.
│ └── scheduler.py # Kör sökning enligt schema
│
├── api/ # Flask backend
│ ├── app.py # Flask app + endpoints
│ ├── models.py # SQLAlchemy modeller
│ └── mail.py # Mailgun integration
│
├── frontend/ # Webbsajten
│ ├── index.html # Landingpage (redan skapad ✅)
│ ├── deals.html # Live deals-sida
│ └── archive.html # Missed deals arkiv
│
├── templates/ # E-postmallar
│ ├── deal_alert.html # "Ny deal! ARN→BKK 3 490 kr"
│ └── weekly_digest.html # Veckans bästa deals
│
├── config.py # API-nycklar, databas
├── requirements.txt # Python dependencies
└── crontab.txt # Cron-schema
3
Databasschema (MySQL)
📋 subscribers – Användare som vill ha deals
| Kolumn | Typ | Beskrivning |
|---|---|---|
| id PK | INT AUTO_INCREMENT | Unikt ID |
| VARCHAR(255) UNIQUE | E-postadress | |
| airports | JSON | Bevakade avgångar: ["ARN","GOT"] |
| destinations | JSON | Önskade destinationer: ["BKK","HKT"] |
| max_price | INT NULL | Max pris i SEK (valfritt) |
| tier | ENUM('free','premium') | Gratis eller betalande |
| created_at | DATETIME | Registreringsdatum |
| confirmed | BOOLEAN DEFAULT 0 | Double opt-in bekräftad |
💰 price_history – Alla priser vi hämtat
| Kolumn | Typ | Beskrivning |
|---|---|---|
| id PK | INT AUTO_INCREMENT | Unikt ID |
| route | VARCHAR(10) | T.ex. "ARN-BKK" |
| price_sek | INT | Pris tur/retur i SEK |
| airline | VARCHAR(100) | Flygbolag |
| departure_date | DATE | Utresedatum |
| return_date | DATE | Hemresedatum |
| stops | INT | Antal stopp (0=direkt) |
| booking_link | TEXT | Deeplink till bokning |
| fetched_at | DATETIME | När priset hämtades |
🔥 deals – Flaggade deals (aktiva + arkiverade)
| Kolumn | Typ | Beskrivning |
|---|---|---|
| id PK | INT AUTO_INCREMENT | Unikt ID |
| route | VARCHAR(10) | T.ex. "CPH-HKT" |
| destination_city | VARCHAR(50) | "Phuket" |
| deal_price | INT | Deal-priset i SEK |
| normal_price | INT | Normalpris i SEK (30d medel) |
| discount_pct | INT | Rabatt i procent |
| airline | VARCHAR(100) | Flygbolag |
| departure_date | DATE | Utresedatum |
| return_date | DATE | Hemresedatum |
| stops | INT | Antal stopp |
| booking_link | TEXT | Deeplink till bokning |
| deal_type | VARCHAR(30) | "Error fare", "Flash sale", "Kampanj" |
| status | ENUM('active','expired') | Aktiv eller utgången |
| found_at | DATETIME | När dealen hittades |
| expired_at | DATETIME NULL | När priset försvann |
| notified | BOOLEAN DEFAULT 0 | Har mail skickats? |
📊 route_stats – Beräknade medelvärden per rutt
| Kolumn | Typ | Beskrivning |
|---|---|---|
| route PK | VARCHAR(10) | "ARN-BKK" |
| avg_price_30d | INT | Medelpris senaste 30 dagarna |
| min_price_30d | INT | Lägsta pris senaste 30 dagarna |
| avg_price_90d | INT | Medelpris senaste 90 dagarna |
| sample_count | INT | Antal prispunkter |
| updated_at | DATETIME | Senast beräknad |
4
Cron-schema
| Jobb | Schema | Cron | Beskrivning |
|---|---|---|---|
| 🔍 Prisbevakning | Var 4:e timme | 0 */4 * * * |
Hämtar priser från API för alla 25 rutter, 3 mån framåt |
| 🧠 Deal-detection | Var 4:e timme | 10 */4 * * * |
Kör 10 min efter prisbevakning. Jämför nya priser mot route_stats |
| 📧 Deal-utskick | Var 4:e timme | 20 */4 * * * |
Skickar mail till matchande prenumeranter för nya deals |
| 📊 Uppdatera stats | 1 gång/dag | 0 3 * * * |
Beräknar om medelpris per rutt (route_stats) |
| 🗑 Rensa gamla priser | 1 gång/vecka | 0 4 * * 0 |
Tar bort price_history äldre än 6 mån |
| ⏰ Expire deals | Var timme | 0 * * * * |
Kollar om aktiva deals fortfarande finns, annars → expired |
5
API Endpoints (Flask)
POST
/api/subscribe
Registrera ny prenumerant. Body: { email, airports[], destinations[] }. Skickar bekräftelsemail.
GET
/api/deals?status=active
Hämta aktiva deals. Visas på sajten i realtid. Filter: route, max_price, stops.
GET
/api/deals?status=expired&limit=20
Hämta utgångna deals för "Deals du missade"-sektionen. Sorterat nyast först.
GET
/api/routes/stats
Hämta medelpris och historik per rutt. Används för destination-korten på sajten.
GET
/api/unsubscribe?token=xxx
Avregistrering via unik token i mailet. GDPR-krav.
6
Utvecklingsfaser
Fas 1 – Nu
Landingpage + Signup + Manuella deals
Vecka 1–2
- Landingpage med deals + missed deals design
- Subdomän thaitrip.wenesthosting.com med SSL
- Landingpage deployad till CyberPanel
- Skapa MySQL-databas MySQL
- Flask API med /subscribe endpoint Python Flask
- Mailgun integration för bekräftelsemail Mailgun
- Koppla signup-formulären till API:et JS fetch
- Hitta deals manuellt och lägg in i databasen
💡 Mål: Få upp sajten, börja samla e-postadresser. Hitta deals manuellt via Google Flights och skicka dem via Mailgun medan crawlern byggs.
Fas 2
Automatisk prisbevakning + Deal-detection
Vecka 3–4
- flight_search.py – Flight API-klient Python requests
- routes.py – Alla 25 rutter definierade
- Spara priser i price_history SQLAlchemy
- Cron job var 4:e timme
- deal_detector.py – Jämför mot medelpris
- Automatisk deal-flaggning
- E-postmall för deal alerts Jinja2 + Mailgun
- Sajten visar live deals från databasen JS fetch → API
💡 Mål: Deals hittas automatiskt och skickas till prenumeranter. "Missed deals" fylls på med riktiga historiska deals.
Fas 3
Hotell-deals + Användarfilter
Vecka 5–8
- Booking.com Affiliate API för hotellpriser REST API
- Hotell-deals i samma system
- Paket-deals: Flyg + Hotell-kombination
- Användarens preferenser: avgångsflygplats, budget, resetyp
- Personliga deal-mail baserat på filter
- Veckans digest-mail med bästa deals
Fas 4
Premium + Skalning
Månad 3+
- Premium-tier med Stripe-betalning Stripe
- SMS-notiser för error fares Twilio
- Fler destinationer (bortom Thailand?)
- App / PWA
- Egen domän thaitrip.se
- SEO-optimering och content marketing
7
Intäktsmodell
🆓 Gratis
0 kr
- 1 avgångsflygplats
- 2-3 deals per vecka
- Veckans digest-mail
- Deals visas 24h fördröjt
⭐ Premium
59 kr /månad
- Alla avgångsflygplatser
- Alla deals direkt (ingen fördröjning)
- Error fares & flash sales först
- Personliga filter (budget, datum)
- Hotell-deals
- SMS-alert vid extrema deals
💰 Affiliate-intäkter (passiv): Kiwi.com Tequila betalar provision på bokningar via dina deeplinks. Booking.com affiliate ger ca 4% per hotellbokning. Detta genererar intäkt oavsett om användaren betalar premium eller inte.