Commit Graph

114 Commits

Author SHA1 Message Date
8c950bbe8f Hae postit -nappi synkkaa myös Zammadin + suljettu tiketti avautuu uutena
1. Hae postit -nappi ajaa nyt myös zammad_sync automaattisesti
   sähköpostien haun jälkeen (ohitetaan hiljaa jos Zammad ei käytössä).
2. Kun suljettuun/ratkaistuun tikettiin tulee uusi viesti,
   tiketti avautuu uudelleen "uusi"-tilaan (aiemmin "käsittelyssä").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:19:51 +02:00
b9a76d76e5 Korjaa Zammad-ryhmien näkyvyys asetuksissa — hae API:sta eikä muistista
Zammad-ryhmät eivät näkyneet postilaatikoiden näkyvyydessä koska ne
haettiin tickets-globaalista joka on tyhjä ennen tiketti-tabin avaamista.
Lisätty ticket_zammad_groups API-endpoint joka hakee uniikit ryhmät
suoraan tietokannasta.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:15:55 +02:00
056de5054d Vaihda brändäys: Noxus Intra → Noxus HUB © Empor Oy 2026
Kaikki viittaukset "Noxus Intra" vaihdettu muotoon "Noxus HUB" koko
koodikannassa. Footer ja login-sivu näyttävät nyt "Noxus HUB © Empor Oy 2026".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:49:00 +02:00
08bce71b5b Paginointi asiakaspalveluun + Zammad-ryhmät näkyvyysasetuksiin
- Paginointi: 100 tikettiä/sivu, navigointipalkki sivujen välillä
- Filtterit resetoivat sivunumeron 1:ksi
- Select All valitsee vain nykyisen sivun tiketit
- Zammad-synkronointi tallentaa source=zammad ja zammad_group
- Postilaatikoiden näkyvyysasetuksissa Zammad-ryhmät (Zammad)-merkinnällä
- Zammad-ryhmien piilotus filtteröi tiketit samalla tavalla kuin postilaatikot

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:20:25 +02:00
cc6e5c2653 Noxus-logo + API-tabi piiloon ilman integraatioita
- Luotu Noxus SVG-logo (violetti heksagoni + N)
- Demo-yritys nimetty uudelleen Noxukseksi violetilla värillä
- API-tabi piilotettuna ellei yrityksellä ole integraatioita päällä
  (superadmin näkee aina)
- check_auth palauttaa has_integrations-lipun

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:14:17 +02:00
1752397161 Fix: ZammadClient lisää https:// automaattisesti URL:iin
Kun Zammad-URL syötettiin ilman protokollaa (esim. desk.web1.fi),
cURL ei osannut muodostaa oikeaa osoitetta ja synkronointi epäonnistui.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:56:37 +02:00
6a12da858f Fix: superadmin pääsy kaikkiin yrityksiin
Superadmin-käyttäjällä oli user_companies-taulussa vain yksi yritys,
joten hän ei voinut vaihtaa tai muokata muita yrityksiä (esim. intra.web1.fi).
Nyt superadmin saa kaikki yritykset sessioon loginissa ja check_auth:ssa,
ja requireCompany() + company_switch ohittavat company-tarkistuksen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:24:03 +02:00
dbf2d2b89a Korjaa integraatio-endpointit: $companyId = requireCompany() kaikissa caseissa
Kaikki integraatio/zammad-endpointit kutsuivat requireCompany() ilman
return-arvon talteenottoa, jolloin $companyId oli null ja aiheutti
Fatal error. Korjattu: integrations, integration_save, integration_test,
zammad_groups, zammad_sync, zammad_reply.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:19:35 +02:00
bfa30009a9 Integraatiot: checkboxit vain päälle/pois Yrityksissä, kaikki asetukset API-tabissa
- Yritykset-tab: integraatio-checkboxit tallentavat vain enabled-tilan
- API-tab: Zammad/Saatavuus/Telegram kortit näkyvät kun integraatio päällä
- Zammad-asetukset (URL, token, ryhmät, synkronointi) kokonaan API-tabissa
- integration_save: tyhjä config ei ylikirjoita olemassaolevia asetuksia

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:11:31 +02:00
4a46ce56f3 Zammad-asetukset API-välilehdelle, integraatio-checkboxit erilliseksi kortiksi, korjaa tyyppi puuttuu -virhe
- Integraatiot erillinen table-card yrityksen asetuksissa (vain superadmin)
- Zammad-konfiguraatio (URL, token, ryhmät, synkronointi) siirretty API-tabiin
- Saatavuus-API, Telegram ja Zammad kortit näkyvät API-tabissa kun integraatio on enabloitu
- Korjattu integration_save ja integration_test: puuttuva $input json_decode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:00:36 +02:00
648cb949ac Superadmin-rajoitus: moduulit, integraatiot ja IP-asetukset vain pääkäyttäjälle + captcha-sessiokorjaus
- Moduulit, integraatiot ja IP-rajoitukset piilotetaan yritysadminilta (vain superadmin näkee)
- Saatavuus-API ja Telegram checkboxit tallentavat tilan heti muutoksessa
- session_regenerate_id(false) estää race conditionin kirjautumisen jälkeen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:49:57 +02:00
fa8aaed11e Lisää Zammad-integraatio ja modulaarinen integraatiot-hallinta
- Uusi integrations-taulu tietokantaan (moduulimalli: type, enabled, config)
- ZammadClient-luokka: tiketit, artikkelit, vastaukset, ryhmät
- API-endpointit: integration_save, integration_test, zammad_sync, zammad_reply, zammad_groups
- Synkronointi: Zammad-tiketit → intran tiketit, artikkelit → viestit
- Vastaukset: Zammad-tiketteihin vastaus kulkee Zammad API:n kautta (→ O365)
- UI: Integraatiot-osio API-välilehdellä, toggle-kytkimet, Zammad-konfiguraatio
- tickets.zammad_ticket_id ja ticket_messages.zammad_article_id linkitys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:25:51 +02:00
1aea4bde20 Tiukempi IP-rajoitus: estä kirjautuminen ja suojaa asetukset
- Login: jos kaikki käyttäjän yritykset IP-estetty → estä
  kirjautuminen kokonaan. Valitsee automaattisesti ei-estetyn
  yrityksen aktiiviseksi.
- check_auth: jos aktiivinen yritys IP-estetty → vaihda
  sallittuun. Jos kaikki estetty → kirjaa ulos.
- company_update: vain superadmin saa muuttaa allowed_ips-kenttää.
  Estää adminia poistamasta IP-rajoitusta itseltään.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:49:24 +02:00
771d288338 Käyttäjän poisto: admin poistaa vain yrityksestä, ei kokonaan
Admin poistaa käyttäjän vain nykyisestä yrityksestä (user_companies).
Käyttäjä poistetaan kokonaan vasta kun ei kuulu enää yhteenkään
yritykseen. Superadmin poistaa edelleen kokonaan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:13:23 +02:00
df2d6d2d83 Korjaa automaattisäännöt ja viestien duplikaattiesto
- Sääntöjen kenttänimet: DB käyttää type_set/status_set mutta
  API lähetti set_type/set_status → nyt dbSaveTicketRule hyväksyy
  molemmat ja matching lukee oikeat DB-kenttänimet
- Migraatio: täytä fetched_message_ids olemassaolevien tikettien
  message_id:illä niin poistetut viestit eivät tule takaisin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:52:22 +02:00
0b04fd1d5a Korjaa ticket_fetch ja sähköpostien duplikaattiongelma
- Korjaa implode()-bugi: $email['to'] on string, ei array
- Lisää fetched_message_ids-taulu joka estää poistettujen
  tikettien uudelleenluonnin seuraavassa haussa
- Viestit haetaan postilaatikosta vain kertaalleen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:21:27 +02:00
656b5042e4 Asiakaspalvelu: alinavi-uudelleenjärjestely + tikettityyppien hallinta
Vastauspohjat, Säännöt ja Asetukset siirretty omiksi alinaveikseen
tikettilistan overlay-napeista. Säännöt-välilehdelle lisätty
tikettityyppien hallinta (lisää/poista). Tyypit tallennetaan
tietokantaan yrityskohtaisesti ja populoidaan dynaamisesti
kaikkiin dropdown-valikoihin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:52:54 +02:00
306dc6c5cc Automaattisäännöt: vastaanottaja-ehto, prioriteetti, abuse-tyyppi
- Lisää "Vastaanottaja sisältää" -ehto (to_contains) sääntöihin
- Lisää "Aseta prioriteetti" -toimenpide (set_priority)
- Lisää "Abuse" tikettityyppi
- Korjaa DB-schema: subject_contains, to_contains, enabled, set_priority, set_tags sarakkeet
- Parsii To-headerit sähköposteista säännön matchausta varten
- Mahdollistaa esim. abuse@-postien automaattisen tyypityksen ja prioriteetin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:27:29 +02:00
70bd095b24 NetAdmin: Gateway-kenttä, IPAM-integraatio VLAN/IP-tietoihin
- Lisää Gateway-sarake ja -valitsin NetAdmin-näkymään (devices-linkitys)
- VLAN ja IP näytetään IPAM:sta automaattisesti asiakkaan nimellä
- Muokkausmodaalissa asiakkaan IPAM VLANit/IP:t näkyvät ensimmäisinä
- DB: gateway_device_id LEFT JOIN devices, IPAM-enrichment API:ssa

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:09:52 +02:00
3fe45b217c Dokumenttikansiot asiakaskohtaisiksi
- Lisää customer_id sarake document_folders-tauluun (ALTER TABLE migraatio)
- dbLoadFolders() tukee nyt customer_id suodatusta
- dbSaveFolder() tallentaa customer_id:n kansioon
- API document_folders endpoint vastaanottaa customer_id parametrin
- JS: kansiot ladataan ja luodaan asiakaskohtaisesti (currentDocCustomerId)
- Jokaisen asiakkaan kansiorakenne on nyt itsenäinen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:04:03 +02:00
663c37c7a7 Korjaa laitetilan poisto: siivoa viittaukset ennen poistoa
- dbDeleteLaitetila nollaa devices.laitetila_id, devices.site_id
  ja ipam.site_id ennen laitetilan poistoa
- API: parempi virhekäsittely (\Throwable), logi, tyhjä ID tarkistus
- Tiedostojen poisto: @-suppression ja GLOB_BRACE hidden-tiedostoille

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:59:03 +02:00
8e9fa76f9c Yhdistä Sijainnit ja Laitetilat samaksi konseptiksi
Sijainnit (sites) ja Laitetilat olivat käytännössä sama asia.
Nyt kaikki hallitaan Laitetilat-välilehdeltä:
- DB-migraatio kopioi vanhat sites → laitetilat (sama ID säilyy)
- Laitteiden site_id päivitetty automaattisesti laitetila_id:ksi
- IPAM JOINaa nyt laitetilat-taulua sites:n sijaan
- Sijainnit sub-tab poistettu Tekniikasta
- Laiteformissa yksi "Sijainti / Laitetila" dropdown
- Sites API-endpointit poistettu (sites palauttaa laitetilat)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:54:03 +02:00
13feb31304 Laitetilat: laitelinkit kortteihin + Sijainnit pois yritysasetuksista
Laitetila-laite-yhteys:
- Lisätty laitetila_id -sarake devices-tauluun
- Laite-lomakkeeseen uusi "Laitetila" dropdown (Tekniikka → Laitteet)
- Laitetila-kortit näyttävät laitemäärän ja laitechipit (max 4 + "+N muuta")
- Laitetilan detailnäkymässä taulukko tilan laitteista (nimi, tyyppi, malli, IP, ping)
- dbLoadLaitetilat palauttaa device_count ja devices-listan per laitetila

Yritysasetukset:
- Poistettu Sijainnit-osio yrityksen tiedoista (hallitaan Tekniikka → Sijainnit)
- Sijainnit sub-tab Tekniikassa pysyy ennallaan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:39:45 +02:00
2cacea2a2c Liittymien VLAN/Laite/IP-kentät hakukentiksi + IP/verkko-tuki
- Korvattu select-dropdownit hakukentillä (searchable combobox)
  - Kirjoittamalla suodattaa tuloksia nimellä, IP:llä, sijainnilla jne.
  - Nuolinäppäimillä navigointi, Enter valitsee, Esc sulkee
  - Vapaan tekstin syöttö mahdollista jos IPAM:sta ei löydy
- IP-kenttä tukee nyt myös verkkoja (subnet/prefix) IP-osoitteiden lisäksi
  - Vapaat IP:t, varatut IP:t ja verkot ryhmitelty omiin osioihinsa
  - Badge-värit: vihreä (vapaa), punainen (varattu), sininen (subnet)
- Sama hakukenttä-komponentti sekä netadmin-modalissa että asiakasformissa
- API palauttaa nyt subnetit IP-listan mukana

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:29:05 +02:00
7ed17c163f Liittymien VLAN/Laite/IP-kentät hakevat nyt tiedot IPAM:sta ja laiterekisteristä
- NetAdmin liittymälomakkeen VLAN, Laite ja IP muutettu tekstikentistä dropdown-valikoiksi
- Asiakasformin liittymäkentät samoin muutettu dropdown-valikoiksi
- Dropdownit populoidaan IPAM:n VLANeista, IP-osoitteista ja Tekniikan laiterekisteristä
- IP-dropdown ryhmittelee vapaat ja varatut IP:t optgroupeilla
- Laite-dropdown näyttää ping-statuksen, hallintaosoitteen ja mallin
- VLAN-dropdown näyttää VLAN ID:n, nimen ja sijainnin
- Jos nykyinen arvo ei ole IPAM/laiterekisterissä, näytetään se (manuaalinen)-lisätekstillä
- IPAM-tilan automaattipäivitys: kun liittymälle asetetaan IP, IPAM merkitsee sen varatuksi
- Kun IP poistetaan tai vaihdetaan, vanha IP vapautetaan IPAM:ssa automaattisesti
- API palauttaa nyt vlans ja ips -listat netadmin_connections-endpointissa

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:20:42 +02:00
cb52dbfabe Dokumenttien poisto kaikille + versioiden säilytysrajoitus
- Poisto-nappi näkyy dokumentin luojalle (ei enää vain admin)
- API: document_delete sallii poiston adminille tai luojalle
- Uusi max_versions-sarake documents-tauluun (oletus 10)
- Versioiden automaattinen pruning: uuden version tallennuksen yhteydessä
  poistetaan vanhimmat versiot jos yli max_versions (tiedostot levyltä myös)
- Valittavissa per dokumentti: 5, 10, 20, 50 tai rajaton

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:35:50 +02:00
f40b387383 Dokumentit: kokousmuistiot, kansiorakenne, sub-tabit, asiakaslinkkaus
- Uusi dokumenttityyppi "kokousmuistio" jolla inline tekstieditori (ei tiedostopohjainen)
- document_versions.content -sarake kokousmuistioiden tekstin tallennukseen
- Sub-tabit Dokumentit-välilehdelle (Kaikki / Kokoukset) Tekniikka-mallin mukaan
- Kansiorakenne: document_folders-taulu, kansionavigaatio breadcrumbsilla
- Uudet API-endpointit: document_folders, document_folder_save/delete, document_content_save, document_move
- Asiakasprofiilin Dokumentit-osio: näyttää linkitetyt dokumentit + pikanapit luontiin
- Asiakasprofiilista voi avata dokumentin suoraan tai luoda uuden linkitettynä asiakkaaseen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:19:05 +02:00
150c774bb3 Siirrä allekirjoitukset Asiakaspalvelu-välilehdelle + postilaatikoiden piilotus
- Uusi "Omat asetukset" -näkymä Asiakaspalvelu-tabiin (allekirjoitukset + mailbox-näkyvyys)
- Uusi user_hidden_mailboxes-taulu piilotettavien postilaatikoiden tallennukseen
- API: profile_update + check_auth tukevat hidden_mailboxes-listaa
- Tikettilista suodattaa piilotettujen mailboxien tiketit automaattisesti
- Reply-formin mailbox-dropdown piilottaa piilotetut postilaatikot
- Allekirjoitukset poistettu Oma profiili -modalista (siirretty Asiakaspalvelu-asetuksiin)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:33:38 +02:00
16d53c71be Yritysvaihto päivittää layoutin aktiivisen yrityksen mukaan
check_auth palauttaa nyt aktiivisen yrityksen branding-tiedot (väri, logo,
nimi, subtitle) domain-pohjaisen sijaan. Kun käyttäjä vaihtaa yritystä,
layout päivittyy vaihdetun yrityksen ulkoasun mukaiseksi.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:35:48 +02:00
68c9075676 Yrityskohtaiset käyttäjäroolit + IP-rajoitus bugikorjaus
- Lisää role-sarake user_companies-tauluun (admin/user per yritys)
- Migraatio: kopioi vanhat admin-roolit user_companies-tauluun, muuta globaali admin → user
- Päivitä dbSaveUser/dbLoadUsers/dbGetUser/dbGetUserByUsername käsittelemään company_roles
- isCompanyAdmin() tarkistaa nyt yrityskohtaisen roolin (session company_role)
- requireAdmin() käyttää isCompanyAdmin():ia
- requireCompany() tarkistaa IP-rajoituksen (siirretty login/check_auth:sta)
- Login ei enää estä kirjautumista IP:n perusteella, vaan merkitsee ip_blocked
- check_auth näyttää kaikki yritykset, IP-estetyt merkitään ip_blocked:lla
- company_switch palauttaa company_role ja päivittää session
- Frontend: käyttäjälomakkeessa yrityskohtaiset rooli-dropdownit (admin/käyttäjä)
- Frontend: yritysvaihto päivittää admin-näkyvyyden company_rolen mukaan
- Frontend: yritysvalitsimessa IP-estetyt yritykset näkyvät "(IP-rajoitus)" -tekstillä

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:45:18 +02:00
6628eaeb89 Korjaa IPv6 IP-allow: IPv4-mapped IPv6 ↔ IPv4 cross-matching
Kun palvelin käyttää IPv6:ta, client IP voi tulla muodossa
::ffff:192.168.1.1 vaikka allow-listassa on 192.168.1.1.
Nyt isIpAllowed() tunnistaa IPv4-mapped IPv6 -osoitteet ja
vertailee molemmissa muodoissa (IPv4 ↔ ::ffff:IPv4).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:02:16 +02:00
9208ab387a NetAdmin: liittymän muokkausmodal + nopeusvalikko dropdowniksi
Liittymärivin klikkaus avaa modal-ikkunan jossa voi muokata kaikkia
kenttiä (osoite, nopeus, VLAN, laite, portti, IP). Yhteysnopeus
muutettu dropdown-valikoksi sekä NetAdmin-modalissa että asiakkaan
liittymälomakkeessa. Vakionopeudet: 10/10 - 10000/10000.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:26:41 +02:00
f05313530f NetAdmin-moduuli: liittymien listaus ja haku
Kokoaa kaikki asiakkaiden liittymät yhteen näkymään haulla ja suodattimilla.
Sarakkeet: asiakas, osoite, kaupunki, nopeus, VLAN, laite, portti, IP, hinta.
Suodattimet: kaupunki, nopeus, laite. Laitetietojen ping-status näkyvissä.
Klikkaus avaa asiakkaan muokkaukseen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:39:24 +02:00
e6fa65165e Versioiva dokumentinhallinta + Laitetilat-moduuli
Dokumentit: versioiva tiedostonhallinta asiakkaille (sopimukset, laskut, ohjeet).
Sisältää versiohistorian, tiedostojen latauksen/palautuksen ja asiakas-suodatuksen.

Laitetilat: laitetilojen hallinta kuvagallerialla ja tiedostolistauksella.
Sisältää korttipohjaisen listanäkymän, kuvien esikatselun ja tiedostojen hallinnan.

Molemmat moduulit: 4 DB-taulua, 14 API-endpointtia, täysi CRUD, tiedostoupload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:18:32 +02:00
093f40ac09 Osatehtävät (subtaskit) TODO-tehtäviin
Uusi todo_subtasks-taulu + 3 API-endpointtia (add/toggle/delete).
Tehtävän lukunäkymässä checkbox-lista osatehtäville, lisäys
Enter-näppäimellä tai Lisää-napilla. Valmiit yliviivataan.
Tehtävälistassa näkyy edistyminen (esim. ☑ 2/5).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:45:47 +02:00
fb22e09c0b Korjaa isAdmin() -> isCompanyAdmin() todo-endpointeissa
isAdmin() ei ollut olemassa, oikea funktio on isCompanyAdmin().
Aiheutti PHP fatal errorin ja tyhjän vastauksen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:14:01 +02:00
77aa809439 Korjaa todo_status/assign: poista dbLoadTodo-kutsu joka kaatui
dbLoadTodo hakee comments+time_entries lisätauluista jotka
saattoivat puuttua/kaatua -> tyhjä vastaus. Nyt käytetään
kevyttä SELECT type,company_id kyselyä oikeustarkistukseen
ja suoraa UPDATE-lausetta. Koko endpoint try-catchissä.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:11:20 +02:00
e53a6babdb Debug: paranna virhekäsittelyä todo_status + apiCall JSON parse
apiCall palauttaa nyt selkeän virheen jos palvelimen vastaus
ei ole validia JSON:ia (+ logittaa console.error). todo_status
palauttaa JSON-virheen myös edge-caseissa.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:52:50 +02:00
b0c9817aaa Korjaa todo status/assign: suora UPDATE dbSaveTodo:n sijaan
dbSaveTodo kaatui koska dbLoadTodo palauttaa ylimääräisiä
kenttiä (comments, time_entries, total_hours). Vaihdettu
suoraan UPDATE-lauseeksi + lisätty JSON-virhevastaukset
kaikkiin virhetilanteisiin (404/403/500).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:49:49 +02:00
e3891463e9 Tehtäviin Tyyppi-kenttä (tekniikka, laskutus, myynti, asennus, muu)
Uusi category-sarake todosiin. Näkyy listassa badgena, lomakkeessa
dropdownina ja lukunäkymässä. Tyypillä voi myös suodattaa listaa.
Värikoodatut badget kullekin tyypille.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:35:17 +02:00
4a1dccb6ff Uusi TODO-moduuli: Tehtävät + Kehitysehdotukset + Ajanseuranta
Talon sisäinen tehtävienhallinta kahdella alatabilla:

Tehtävät (admin luo):
- Prioriteetti (normaali/tärkeä/kiireellinen), status, deadline
- Vastuuhenkilö-osoitus, inline-muokkaus lukunäkymässä
- Aikakirjaukset: pvm, tunnit, kuvaus - kaikki voivat kirjata
- Myöhästyneet = punainen reunus, lähestyvät = keltainen
- Kommentointi kaikille käyttäjille

Kehitysehdotukset (kaikki voivat luoda):
- Status: ehdotettu → harkinnassa → toteutettu/hylätty (admin muuttaa)
- Kommentointi kaikille
- Ehdottaja voi muokata omia

Tietokanta: 3 taulua (todos, todo_comments, todo_time_entries)
API: 10 endpointtia oikeustarkistuksineen
Frontend: Sub-tab navigointi, kortti-grid, 3-näkymämalli per alatabi

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:14:53 +02:00
9cb2eeeb62 Korjaa IMAP sähköpostien body-dekoodaus kokonaan
Vanha fetchBody haki aina BODY[1] ja käytti haurasta regexiä
koodauksen tunnistamiseen BODYSTRUCTURE:sta → monet viestit
jäivät raakana base64/quoted-printable -muodossa.

Uusi toteutus:
- Parsii BODYSTRUCTURE:n nesting-syvyyden → oikea section-numero
  (TEXT/1/1.1 riippuen onko single-part/multipart/sisäkkäinen)
- Joustava regex koodauksen tunnistamiseen (tukee NIL/"str" body-id/desc)
- Automaattinen QP-tunnistus (=XX -koodien haku) base64:n lisäksi
- extractPlainFromMultipart: jos BODY[1] palauttaa raakaa
  multipart-dataa boundary-rajoineen, parsii text/plain tai
  text/html suoraan MIME-osista
- error_log debug-lokit BODYSTRUCTURE/section/encoding tiedoilla

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:43:17 +02:00
565259423d Ohjeet: kuva-upload -toiminto Markdown-editoriin
- "Kuva" -nappi toolbarissa avaa tiedostovalitsimen
- Kuva uploadataan serverille (max 5MB, PNG/JPG/GIF/WebP)
- Markdown ![kuva](url) -tagi lisätään automaattisesti editoriin
- Kuva renderöityy lukunäkymässä ja esikatselussa
- API: guide_image_upload (upload) + guide_image (serve)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:24:36 +02:00
7c4060bfa8 Ohjeet-moduuli: Confluence-tyylinen tietopankki asiakaspalvelijoille
Uusi moduuli "Ohjeet" jossa ylläpitäjä voi kirjoittaa ohjeita
asiakaspalvelijoille miten asioita tehdään.

Ominaisuudet:
- Korttipohjainen listanäkymä (grid) hakutoiminnolla ja kategoriasuodatuksella
- Markdown-editori toolbarilla (B, I, H2, H3, listat, linkit, koodi, lainaukset)
- Esikatselu-toggle muokkausnäkymässä
- Artikkelien lukunäkymä renderoitulla Markdownilla
- Kategorioiden hallinta (lisää/poista)
- Tagit ja kiinnitys (pinned) -toiminto
- Oikeushallinta: kaikki lukevat, admin luo/muokkaa/poistaa
- Moduuli näkyy/piiloutuu yrityskohtaisista asetuksista
- Muutokset kirjautuvat muutoslokiin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:19:00 +02:00
6a84231cce IPAM: VLAN-duplikaattivaroitus "jatketaanko silti" -dialogilla
API palauttaa 409 kun VLAN-numero on jo olemassa, frontend
näyttää confirm-dialogin. Käyttäjä voi valita jatkaako vai ei.
IP/verkko-duplikaatti estää edelleen kokonaan (400).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 10:08:34 +02:00
44053d27f2 IPAM: duplikaatti-IP-tarkistus, vapaat lohkot, asiakas-kentän poisto + varattu oletus
- Duplikaatti-IP/verkko -tarkistus: estää saman verkko-osoitteen lisäämisen kahdesti
- Vapaan tilan näyttö: kun subnet avataan, näytetään vapaat osoitelohkot lasten välissä (vihreä "Vapaa"-rivi)
- Asiakas-kenttä poistettu IPAM-näkymästä (taulukot, lomake, haku)
- Varattu oletustilaksi verkkoa/VLANia lisättäessä

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:50:18 +02:00
8a73423bf1 Auto-VLAN käyttää subnetin nimeä + poistettu Reserved-tila
- Auto-VLAN saa subnetin/IP:n nimen (ei enää geneeristä 'VLAN X')
- Poistettu 'Reserved' tila-vaihtoehto lomakkeesta (Varattu riittää)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:36:57 +02:00
2686377fe2 Auto-VLAN: verkon/IP:n VLAN-numero luo VLANin automaattisesti
Kun tallennetaan subnet tai IP jossa on VLAN-numero, tarkistetaan
löytyykö kyseinen VLAN jo listalta. Jos ei, luodaan se automaattisesti
VLAN-luetteloon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:31:54 +02:00
03c9a7605a Auto-IPAM: laitteen hallintaosoite varataan automaattisesti
Kun laitteelle tallennetaan hallintaosoite (IP), IPAM:iin luodaan
automaattisesti varattu IP-merkintä laitteen nimellä ja sijainnilla.
Jos IP on jo IPAM:issa, päivitetään se varatuksi laitteelle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:22:16 +02:00
1dc04326aa IPv6-tuki IP-rajoitukseen
Vaihdettu ip2long() -> inet_pton() joka tukee sekä IPv4 että IPv6.
CIDR-alueet toimivat molemmilla (esim. 2001:db8::/32).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:54:40 +02:00