Commit Graph

265 Commits

Author SHA1 Message Date
bbfff2f8b5 Mobile responsiveness + IP allow list comments
Mobile improvements:
- Fix overflow issues with global max-width/overflow-x hidden
- Stack ticket detail selects on mobile instead of one long row
- Compact header: hide less important buttons, scrollable right side
- Stat cards in 2-column grid on mobile
- Force flex-wrap on inline-styled flex containers
- Hide subtitle and user-info on small phones
- Ticket selects full-width on small phones

IP allow list:
- Support # comments after IP addresses (e.g. "192.168.1.1 # Office VPN")
- Updated placeholder with comment examples

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:49:07 +02:00
77dc790b0f Add mobile responsiveness + PWA support
Mobile (768px):
- Tab bar: horizontal scroll with momentum, hidden scrollbar
- Header: compact layout, smaller fonts
- Tables: horizontal scroll, hide-mobile class for less important cols
- Modals: bottom-sheet style, full width
- Touch targets: min-height 36px for buttons/selects
- Toolbar: stacks vertically
- Stat cards: compact

Small phone (480px):
- Even more compact header and tabs
- Smaller table cells
- iOS zoom prevention (16px font on inputs)

PWA:
- manifest.json for Add to Home Screen
- apple-mobile-web-app-capable meta tags
- theme-color for status bar
- overscroll-behavior: none (prevent pull-to-refresh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:33:48 +02:00
45de863d07 Security: defense-in-depth company isolation for all operations
Critical fixes:
- company_logo_upload: validate user has access to target company
- All delete functions (db.php): accept optional company_id parameter
  for defense-in-depth filtering (customers, devices, ipam, guides,
  leads, tickets, archives, mailboxes, rules, templates, todos)
- All API delete calls now pass company_id to db layer
- ticket_bulk_delete: per-ticket company_id filtering
- todo_comment/time/subtask operations: verify todo belongs to company
- dbGetMailbox: optional company_id scoping, used in smtp_test
- requireCompanyOrParam: no longer mutates session permanently
- Fix _dbFetch typo in zammad_attachment (was runtime error)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 18:27:13 +02:00
a73cce678e Sync ticket status to Zammad + prevent closed tickets reopening
- When changing ticket status in intra, now syncs to Zammad too
  (close in intra → close in Zammad, etc.)
- Prevent Zammad sync from reopening locally closed tickets
  unless Zammad has genuinely new activity (updated_at changed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:15:16 +02:00
b4a85a28a5 Group users by company + allow admins to set user/admin role
- Superadmin sees users grouped by company with header rows
- Admins can now set user or admin role when creating/editing users
- Admin role change restricted to own company only
- Prevents admin from modifying superadmin roles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:16:04 +02:00
a94d1edee0 Add SSL certificate provisioning button for superadmin
- New provision_ssl API endpoint runs certbot for new domains
- SSL button appears next to domain textarea for superadmin
- Shell script on server handles Apache config + Let's Encrypt
- DNS check skips domains without resolution to avoid certbot errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:09:34 +02:00
d4e06fd586 Optimize Zammad sync: skip closed tickets in incremental sync
- Incremental sync now excludes closed/merged/removed tickets from query
- Full sync still fetches everything
- Reopened tickets (closed→new/open in Zammad) are handled correctly:
  existing ticket is updated instead of creating duplicate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:56:38 +02:00
15223760f5 Auto-update ticket status to käsittelyssä on first reply
- zammad_reply endpoint now sets intra status uusi→kasittelyssa
- Also updates Zammad ticket state to open
- Fixed stateMap: Zammad open now maps to kasittelyssa instead of avoin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:53:59 +02:00
e2f08304b3 Add deep linking to tickets for easy sharing
Tickets now get a unique URL hash (#support/ticket/ID) when opened.
Copy link button in ticket header copies the full URL to clipboard.
Opening a ticket link navigates directly to the ticket detail view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:20:12 +02:00
f8073a2350 Poista ticket-threadin max-height scroll — koko sivu scrollaa
Viestiketju oli rajoitettu 60vh laatikkoon overflow-y:auto,
joka pakotti scrollaamaan iframemaisesti. Nyt viestit ovat
osa normaalia sivun virtausta.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:29:03 +02:00
3c0cf94f6e Näytä Kehitysehdotukset-alinavi Tehtävät-välilehdellä
Sub-tab-bar oli piilotettu display:none — nyt näkyvillä
samalla tyylillä kuin muissa näkymissä.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:27:22 +02:00
4c7e57da2a Sulje-nappi harmaaksi samalla värillä kuin suljettu-badge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:25:47 +02:00
8f5c269c66 Vaihda Tehtävä-napin teksti -> Lisää tehtäväksi
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:23:46 +02:00
6c7fd3289a Sulje-nappi harmaaksi ja X-ikoni pois
Tikettinäkymän Sulje-nappi neutraaliksi btn-secondary-tyylillä
ilman punaista väritystä ja ✕-merkkiä.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:22:58 +02:00
9683e0b552 Vaihda tiketin Poista-nappi Sulje-napiksi
Tiketti merkataan suljetuksi poistamisen sijaan. Ei enää confirm-dialogia.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:13:01 +02:00
79ec93b293 Lisää saatavuus-tikettityyppi + fallback-väri käsin lisätyille tyypeille
- Saatavuus-tyyppi oletuksiin (teal-väri)
- Fallback CSS: tuntemattomat tyypit saavat violetin taustan
- TypeLabel näyttää tyypin nimen isolla alkukirjaimella jos ei löydy labelista

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:24:52 +02:00
6bbd224104 Poista ticket_fetch changelog-kirjaus
Sähköpostien haku ei ole muutostoiminto eikä kuulu muutoslokiin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:06:45 +02:00
0c9a60a90b Siistimpi Hae postit -UX: ei välivaihe-tekstiä, vain vihreä tuloslaatikko
- Poistettu "Haetaan sähköpostit ja synkataan Zammad..." -teksti
- Status-laatikko näytetään vasta kun tulokset on valmiit
- scrollIntoView scrollaa tuloksen näkyviin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:03:44 +02:00
682de29e5a Piilota sidebar-tilastot + laskutus kun hinnat piilossa, oletusnäkymä support
- prices-hidden blurraa nyt myös sidebar-stats (liittymät, laskutus, keskihinta, nopeudet)
- Summary-barin laskutus blurrautuu samalla
- Oletusnäkymä kirjautumisen jälkeen vaihdettu customers → support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:59:39 +02:00
a69fed75e4 Zammad sync performance + liitteiden näyttö tikettilistassa
- Rajoita artikkelien haku max 10 tikettiin per sync (loput on-demand)
- Curl timeout 15s + connect timeout 5s
- Frontend: IMAP ja Zammad haetaan rinnakkain (Promise.allSettled)
- Auto-refresh: Zammad sync ei blokkaa tikettien latausta
- Hakaneula-ikoni (📎) tikettilistassa kun viestissä on liitteitä
- has_attachments, source, zammad_group, ticket_number tikettilistaan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:56:13 +02:00
dc0ed5c75c Liitteiden näyttö Zammad-viesteissä + download proxy
- dbLoadTickets: attachments & zammad_article_id mukaan viestidataan
- ticket_detail on-demand: liitteiden metadata talteen (sama kuin sync)
- Uusi zammad_attachment proxy-endpoint liitteiden lataukseen
- JS: liitteet näkyvät tikettiviesteissä (ikoni, nimi, koko, latauslinkki)
- CSS: .msg-attachments ja .msg-attachment-link tyylit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 03:14:15 +02:00
376912b9ff Liitetiedostot tikettivastausten sähköposteihin + muistiinpanojen piilotus
- Lisää liitetiedostojen tuki vastauslomakkeeseen (📎 Liitä tiedosto -nappi)
- Tuki max 25 MB tiedostoille, useita liitteitä kerralla
- Zammad API: liitteet base64-muodossa attachments-kentässä
- SMTP: multipart/mixed MIME (boundary, Content-Disposition: attachment)
- Sisäiset muistiinpanot (note) suodatetaan pois quoted threadista
  (eivät näy asiakkaille lähtevissä sähköposteissa)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 03:00:30 +02:00
6f1d9ed5d4 BCC-kenttä tiketteihin + To/CC/BCC tallennus + allekirjoituskorjaus
- Lisää BCC-kenttä vastauslomakkeeseen (HTML, JS, API)
- To/CC/BCC tallentuvat tiketille pysyvästi (seuraava vastaus muistaa muutokset)
- Lisää to_email ja bcc sarakkeet tickets-tauluun
- BCC-tuki SMTP-lähetykseen (RCPT TO ilman headeria)
- Korjaa allekirjoitukset: buildSignaturesWithDefaults() generoi nyt oletukset
  myös Zammad-sähköposteille (support@web1.fi ym.), ei pelkille mailboxeille
- Allekirjoituksiin lisätty puhelinnumero

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:54:57 +02:00
3d66319d89 Korjaa sähköpostivastausten välilyönnit: nl2br + &nbsp; pre-wrap:n sijaan
white-space:pre-wrap ei toimi kaikissa sähköpostiohjelmissa/Zammadissa.
Vaihdettu käyttämään nl2br() rivinvaihdoille ja &nbsp; peräkkäisille
välilyönneille, jotka toimivat universaalisti HTML-sähköposteissa.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:46:28 +02:00
1b5b870ea9 Korjaa tikettiviestiluokittelu: outgoing-tyyppi tunnistetaan nyt lähteviksi
Zammad-synkasta tulevat viestit käyttävät tyyppiä 'outgoing' (ei 'reply_out'),
joten ne näkyivät virheellisesti saapuvina (sininen). Nyt molemmat tyypit
tunnistetaan lähteviksi ja näytetään vihreällä taustalla.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:44:10 +02:00
8d5ef864f9 Saatavuuskyselyt: IP-organisaatio, siirrä API-tabiin + sähköpostien formatointi + tikettiviestivärit
- Lisää IP-organisaatio/ISP-kenttä saatavuuskyselyihin (ip-api.com haku)
- Siirrä saatavuuskyselyt-taulukko Asiakkaat-tabista API-asetussivulle
- Korjaa rivinvaihdot ja välilyönnit Zammad-sähköpostivastauksissa (white-space:pre-wrap)
- Korjaa quoted thread: plain-text viestit muunnetaan HTML:ksi oikein
- Tikettiviestiketjun värit selkeämmiksi (sininen=saapuva, vihreä=lähtevä)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:40:32 +02:00
74380a3176 Saatavuuskyselyt: IP/hostname, duplikaattien esto
- Reverse DNS -haku tallentaa hostnamen IP:n rinnalle (paljastaa
  operaattorin ja alueen, esim. dsl-hel-123.elisa.fi)
- Duplikaattikyselyn (sama osoite+postinumero+kaupunki) ei tallenneta
  uudelleen samalle yritykselle
- IP/hostname -sarake lisätty taulukkoon

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:26:16 +02:00
64dc02f432 Korjaa saatavuuskyselyt: näytä kaikkien yritysten kyselyt
Endpoint näytti vain aktiivisen yrityksen kyselyt, mutta kyselyt
tallennetaan API-avaimen yrityksen alle. Nyt näytetään kaikkien
käyttäjän yritysten kyselyt + yrityssarake taulukkoon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:23:40 +02:00
a38c5f4808 Lisää saatavuuskyselyjen keräys ja listausnäkymä
Jokainen nettisivujen kautta tehty saatavuustarkistus tallennetaan
tietokantaan (osoite, postinumero, kaupunki, tulos, IP, referer).
Kyselyt näkyvät Asiakkaat > Saatavuuskyselyt -välilehdellä
sivutettuna taulukkona.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:19:24 +02:00
9ba239478c Lisää viestiketju (quoted thread) tikettivastausten loppuun
Sekä Zammad- että SMTP-vastaukset sisältävät nyt koko viestiketjun
vastauksessa. Zammad-vastauksissa HTML-blockquoteilla, SMTP:ssä
plain-text > -quoting-muodossa. Vain uusi viesti tallennetaan
tietokantaan, ketju näkyy vain lähetettävässä sähköpostissa.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:08:03 +02:00
4086409f99 Välitä To/CC-kentät Zammad-vastauksissa
JS ei lähettänyt käyttäjän muokkaamaa To/CC-kenttää Zammad-vastauksen
mukana — backend käytti aina alkuperäistä lähettäjää tietokannasta.
Nyt käyttäjän syöttämä To/CC välitetään API:lle ja Zammadille.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 02:02:11 +02:00
6e0596959b Korjaa Zammad-vastauksen sähköpostilähetys
Lisätty subtype: 'reply' Zammad-artikkelin luontiin — ilman tätä
Zammad luo artikkelin mutta ei lähetä sähköpostia vastaanottajalle.
Myös plain-text muunnetaan HTML:ksi ja subject saa Re: -etuliitteen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:51:35 +02:00
c4e7f45bca Korjaa allekirjoituksen valinta vastattaessa tiketteihin
Poistettu virheellinen fallback joka valitsi ensimmäisen satunnaisen
allekirjoituksen (esim. serverihuone.com) väärään tikettiin. Nyt
generoidaan oikea oletusallekirjoitus tiketin kontekstin perusteella
(käyttäjänimi + yritys + vastaanottava sähköposti + puhelin).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:47:58 +02:00
627bec1f47 Siirrä Lisää asiakas -nappi Asiakkaat-moduulin toolbariin
Nappi siirretty oikeasta yläkulmasta (header) asiakaslistauksen
hakupalkin viereen, missä se on loogisemmassa paikassa.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:35:33 +02:00
7a20345701 Lisää puhelinnumero yrityksen asetuksiin ja allekirjoituksiin
Puhelinnumero-kenttä yrityksen asetuksissa tallennetaan tietokantaan
ja näkyy automaattisesti kaikissa oletusallekirjoituksissa viimeisenä
rivinä (sekä SMTP- että Zammad-postilaatikoille).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:30:11 +02:00
a105ec7cd9 Oletusallekirjoitus kaikille postilaatikoille ja Zammad-sähköposteille
Jos käyttäjä ei ole vielä tallentanut allekirjoitusta, näytetään
oletuksena: Käyttäjänimi / Yrityksen nimi / sähköpostiosoite.
Toimii sekä IMAP/SMTP-postilaatikoille että Zammad-sähköposteille.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:18:58 +02:00
890b5d932e Lisää allekirjoitukset Zammad-sähköposteille
Asetukset-sivulla näytetään nyt myös Zammad-sähköpostiosoitteet
(esim. support@web1.fi) allekirjoitusten alla. Allekirjoitus liitetään
automaattisesti Zammad-vastauksiin. Tallennetaan avaimella
"zammad:email@osoite.fi". Uusi ticket_zammad_emails API-endpoint
hakee uniikit vastaanotto-osoitteet tietokannasta.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:12:38 +02:00
02a5c08164 Zammad-tiketit: vastaus Zammad API:n kautta + to-osoite + HTML-viestit
1. Zammad-tiketeille näytetään vastaanotto-osoite (esim. support@web1.fi)
   lähettäjäkentässä eikä SMTP-postilaatikkolistaa — vastaus menee
   Zammad API:n kautta.
2. Ensimmäisen artikkelin to-osoite tallennetaan zammad_to_email kenttään
   on-demand artikkelien haussa.
3. Korjattu _dbFetchRow → _dbFetchOne zammad_reply endpointissa.
4. sanitizeHtml() renderöi viestien HTML turvallisesti.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:06:43 +02:00
d3ab0d3e76 Korjaa HTML-renderöinti viesteissä + mailbox-valinta Zammad-tiketeille
1. Sähköpostiviestien HTML renderöidään oikein (br, p, div, a, b, i jne.)
   sen sijaan että tagit näkyisivät raakatekstinä. Sanitoi vaarallisen
   sisällön (script, iframe, on*-attribuutit) pois turvallisesti.
2. Zammad-tiketeillä ei ole mailbox_id:tä, joten aiemmin valittiin aina
   listan ensimmäinen (tuki@serverihuone.com). Nyt näytetään
   "Valitse lähettäjä" placeholder kunnes käyttäjä valitsee oikean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:00:19 +02:00
109dce3f26 Nopeuta Zammad-sync: artikkelit haetaan vasta kun tiketti avataan
Sync hakee nyt vain tikettien metatiedot (status, aihe, ryhmä) —
ei enää satoja getArticles-kutsuja jokaiselle tiketille. Artikkelit
haetaan on-demand ticket_detail-endpointissa kun käyttäjä avaa
tiketin. Nopeuttaa synkkausta dramaattisesti.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:54:11 +02:00
c002072367 Lisää cache-busting versio script.js ja style.css latauksiin
Selain cachetti vanhan script.js:n aiheuttaen showClosed-virheen
vaikka korjaus oli jo palvelimella. Versioparametri pakottaa uuden
latauksen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:42:36 +02:00
cbcfdaa2a3 Optimoi Zammad-sync: inkrementaalinen haku oletuksena
Auto-refresh hakee nyt vain viimeisen synkkauksen jälkeen muuttuneet
tiketit (updated_at + 5min marginaali). Artikkelit haetaan vain
uusille tai muuttuneille tiketeille. "Hae postit" -nappi tekee
edelleen full syncin (full=true). Nopeuttaa autopäivitystä merkittävästi.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:39:24 +02:00
ecc0b06ba5 Zammad-sync automaattisesti autopäivityksessä + mailbox-valinta korjaus
1. Auto-refresh synkkaa Zammadin taustalla ennen tikettien latausta
   (joka minuutti tms. käyttäjän asetuksen mukaan).
2. Tikettiin vastatessa oletuksena valittuna se postilaatikko johon
   viesti alun perin tuli — korjattu string/number vertailu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:33:44 +02:00
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
909108ec30 Korjaa duplikaatti const showClosed -määrittely renderTickets-funktiossa
Aiheutti SyntaxError: Identifier 'showClosed' has already been declared,
joka kaatoi koko sivun (vain footer näkyi).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:11:41 +02:00
053ad2f28e Näytä suljettujen tikettien määrä vain kun Suljetut-täppä valittu
Normaalisti näytetään vain "X avointa tikettiä". Suljettujen määrä
tulee näkyviin suluissa vasta kun käyttäjä ruksaa Suljetut-checkboxin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:03:10 +02:00
b86bb81cc0 Siirrä tikettien yhteenveto- ja sivutuspalkki listan yläpuolelle
Avoimet/uudet/käsittelemättä-palkki ja sivukoon valitsin näkyvät nyt
tikettitaulukon yläpuolella eikä alapuolella.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:02:18 +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
dd9842abee Lisää sivukoon valinnan event listener tikettilistaukseen
Sivukoon valinta (25/50/100/250) toimii nyt - muuttaa TICKETS_PER_PAGE ja
renderöi tikettilistan uudelleen ensimmäiseltä sivulta.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:46:13 +02:00