Commit Graph

78 Commits

Author SHA1 Message Date
86ffcc88de fix: include priority field in ticket list API response
Priority was missing from the tickets list endpoint,
so colors weren't showing in the ticket table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:08:53 +02:00
19d94f8c19 fix: priority color takes precedence over status color in ticket list
Urgent (red) and tärkeä (orange) row colors now override
the "käsittelyssä" green highlight so priority is always visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:02:42 +02:00
4ce9cefa6a refactor: move priority emails to customer card
Priority emails are now per-customer, not per-company.
Each customer can have a list of email addresses that
automatically elevate ticket priority to "tärkeä" when
they send email. Field added to customer form under
"Lisätiedot" section.

Removed separate priority_emails settings from API/rules tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:00:10 +02:00
8485da8cbf feat: ticket reply improvements + priority + templates + Telegram
Reply form:
- Mailbox/sender selection dropdown (choose which email to reply from)
- CC field (auto-filled from incoming email CC, editable)
- Reply templates dropdown (quick insert pre-made responses)

Priority system:
- Three levels: normaali, tärkeä, urgent
- Priority dropdown in ticket detail view
- Priority-based sorting (urgent/tärkeä always on top)
- Visual indicators in ticket list (colored rows, emoji badges)
- Priority emails: per-company email list that auto-sets "tärkeä"

Response templates:
- CRUD management in Settings tab
- Dropdown selector in reply form
- Templates insert into textarea

Telegram alerts:
- Bot token + chat ID configuration in Settings
- Test button to verify connection
- Auto-alert on urgent tickets (both manual and from email fetch)
- Alert on priority email matches

Database changes:
- New tables: reply_templates, customer_priority_emails
- New columns: tickets.cc, tickets.priority
- ALTER TABLE migration in initDatabase()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:42:05 +02:00
3b7def1186 ui: hide header text when logo is set — logo is enough
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:29:13 +02:00
a0ee98cc9b ui: simplify header with logo, auto-refresh on by default
- When company logo is set, show only "Hallintapaneeli" without
  company name (logo identifies the company)
- Ticket auto-refresh checkbox is checked by default
- Auto-refresh starts when switching to support tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:25:46 +02:00
351ed70c6d ui: move theme color to nav tab bar, white header
Header is now white with neutral text colors.
Nav tab bar uses primary-color background with white text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:24:47 +02:00
ac5d2db711 cleanup: remove gdcheck.php - all extensions confirmed working
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:19:32 +02:00
d2ca790e32 feat: auto-extract color from logo + PHP extension check
Added extractDominantColor() JS function that picks the dominant
color from uploaded logo and suggests it as theme color.
Updated gdcheck.php to show all needed extensions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:19:08 +02:00
9797fda7b7 temp: check GD availability
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:17:11 +02:00
caf0ce8aa2 ui: white header bar with primary color accents
Changed header from colored gradient background to clean white
with primary-color text, border-bottom accent line, and updated
button styles. Logos now display nicely against white background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:15:43 +02:00
d8de69b9b9 fix: handle missing fileinfo extension for logo upload
finfo_open() is not available on CloudLinux alt-php84.
Now validates by file extension first, and only uses finfo
if the extension is available. Falls back gracefully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:09:50 +02:00
b4b64fffcc temp: full logo upload test with form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:07:32 +02:00
c3f2c3dbfa temp: filesystem permission check for logo upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:04:45 +02:00
3cfd80ad27 temp: diagnostic script for logo upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:03:25 +02:00
0605b646cf fix: auto-create company logo directory on upload
With MySQL migration, data/companies/{id}/ directories may not exist.
Now creates directory automatically instead of returning 404.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:59:49 +02:00
c8dce63f6e fix: use domain-based branding in check_auth response
check_auth was returning branding based on active company with
wrong field name (company_nimi instead of nimi), causing Noxus Intra
to show instead of company name on refresh. Now uses dbGetBranding()
with the request domain, same as the branding endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:56:52 +02:00
6ae25006b8 data: add intra.empor.fi domain for Empor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:45:46 +02:00
f16d923b8b temp: add Empor domain fix script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:45:13 +02:00
3d37abe6cf data: add intra.web1.fi domain and subtitle for Web1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:43:58 +02:00
e118513f64 cleanup: remove fix_domains.php after use
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:43:25 +02:00
c7d3ee1e70 temp: add fix_domains.php to set Web1 domain and branding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:42:44 +02:00
14cdfafd40 feat: domain-based login restriction
Users can only log in from domains belonging to their assigned company.
E.g. cuitunet users can only log in via intra.cuitunet.fi.
Admin users can still log in from any domain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:36:05 +02:00
1fa366d3ff feat: add ?reset parameter to migrate.php for clean re-run
Drops all tables (with FK checks disabled) before recreating.
Use: migrate.php?reset=1 or php migrate.php --reset

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:28:42 +02:00
b074b7db28 fix: add unicode flag to named param regex for ö/ä chars
Column name yhteyshenkilö contains ö which \w doesn't match
without the /u flag. This caused SQL syntax errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:26:44 +02:00
8a630508f4 fix: add DEFAULT CHARSET=utf8mb4 to all tables
Foreign key constraints fail if charset doesn't match between
referencing and referenced tables. Added utf8mb4 to user_companies,
reset_tokens, and login_attempts tables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:24:25 +02:00
796e1b3072 feat: rewrite db.php from PDO to MySQLi
PDO extension was not available on CloudLinux/alt-php84 server.
MySQLi is available, so rewrote entire database layer to use it.

Added helper functions (_dbRun, _dbFetchAll, _dbFetchOne, etc.)
that handle named parameter conversion and type binding automatically.
All public db*() function signatures remain identical.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:04:14 +02:00
438a9b5070 temp: phpcheck to verify PDO after Plesk change
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:57:35 +02:00
a75ba19fe5 cleanup: remove phpcheck.php diagnostic script
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:28:01 +02:00
1a18da2430 temp: add phpcheck.php to diagnose PDO availability
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:26:51 +02:00
b15efa1758 cleanup: remove setup_config.php after use
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:25:37 +02:00
42571e46f3 temp: add setup_config.php to create db_config.php on server
Will be removed immediately after use.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:24:20 +02:00
2b8e053e52 debug: add error display to migrate.php to see what fails
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:23:35 +02:00
e540ec0448 fix: split initDatabase() into separate exec() calls per table
MySQL/PDO doesn't support multiple CREATE TABLE statements in a single
exec() call. Split into an array of individual statements with a loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:15:55 +02:00
13e0d1255f JSON → MySQL migraatio: tietokantapohjainen datatallennus
Lisätty:
- db.php: PDO-tietokantakerros (kaikki CRUD-funktiot)
- migrate.php: JSON → MySQL migraatioskripti
- db_config.php lisätty .gitignore:en (sisältää tunnukset)

Muutettu:
- api.php: kaikki JSON load/save → db*() funktiot
- session.cookie_samesite: Strict → Lax (captcha-fix alias-domaineilla)
- Poistettu kaikki JSON-tiedosto I/O (paitsi tiedostoupload + logot)

Hyödyt:
- Git deploy ei enää ylikirjoita dataa
- Tiedostolukot ja transaktiot → ei korruptiota
- Parempi suorituskyky isoilla tietomäärillä

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:00:38 +02:00
c714f39bc5 Päivitä admin-salasana admin123 + kaikki tuotantodata
FTP:llä haettu data vanhalta intra.cuitunet.fi:
- 3 käyttäjää, admin-salasana resetoitu admin123
- 4 yritystä brändäyskentillä
- 35 CuituNet-asiakasta

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:31:46 +02:00
eed1ac5639 Migroi kaikki data vanhalta intra.cuitunet.fi -palvelimelta
FTP:llä haettu:
- 4 yritystä (CuituNet, Web1, Empor, Woima Services)
- 35 CuituNet-asiakasta + 1 liidi
- 1 Web1-asiakas
- 3 käyttäjää (admin, Jukka, ville)
- Brändäyskentät lisätty companies.json:iin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:26:11 +02:00
52bf1bd300 Päivitä CuituNetin data vanhalta palvelimelta (intra.cuitunet.fi)
Haettu API:n kautta: 2 asiakasta, 1 liidi.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:24:44 +02:00
78af39b252 Lisää CuituNetin asiakasdata gittiin
Asiakkaat, liidit, tiketit, asetukset, arkisto ja changelog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:19:59 +02:00
712e9a1222 Lisää data-tiedostot gittiin + dynaaminen SITE_URL
- companies.json, users.json, config.json gitin seurantaan
- SITE_URL dynaaminen HTTP_HOST:in mukaan
- MAIL_FROM vaihdettu noreply@noxus.fi
- CuituNet Intra → Noxus Intra sähköposteissa

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:18:23 +02:00
daec42600a Korjaa deploy_data.php - pakota datan ylikirjoitus
initUsers() luo oletusadminin ennen deploy-skriptiä,
joten tiedostot eivät ole tyhjiä. Nyt ylikirjoitetaan aina.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:16:23 +02:00
edefd05ec6 Lisää deploy_data.php - alustaa data tuotantoon
Väliaikainen skripti joka luo companies.json, users.json, config.json
tuotantopalvelimelle. Poistettava käytön jälkeen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:14:07 +02:00
095dc90b6f White-label multi-domain tuki (Noxus Intra)
- CSS-muuttujat: kaikki kovakoodatut #0f3460/#16213e korvattu var(--primary-color)/var(--primary-dark)
- Uudet API-endpointit: branding (julkinen, domain-pohjainen), company_logo, company_logo_upload
- Domain-pohjainen brändäys: HTTP_HOST → yrityksen domains-arrayn matchaus
- Login: domain asettaa oletusyrityksen sessioon
- check_auth: palauttaa branding-objektin (primary_color, subtitle, logo_url)
- company_create/update: käsittelee domains, primary_color, subtitle, logo_file
- Dynaaminen login-sivu, header ja footer (logo, nimi, alaotsikko, värit)
- JS: loadBranding(), applyBranding(), yritysvaihdon brändäyspäivitys
- Admin-paneeli: brändäysasetukset (logo-upload, väri, alaotsikko, domainit)
- Git-repo siirretty intra.noxus.fi:hin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:44:49 +02:00
918a5ff120 Lisää sähköpostiallekirjoitus per käyttäjä per postilaatikko
- Allekirjoitukset tallennetaan users.json:iin (signatures-objekti, avaimena mailbox_id)
- Käyttäjälomakkeessa dynaamiset textareat jokaiselle postilaatikolle
- Allekirjoitus liitetään automaattisesti sähköpostivastauksiin (ticket_reply)
- Esikatselu näkyy tikettivastauslomakkeen alla
- Muistiinpanoihin (ticket_note) ei lisätä allekirjoitusta
- Uusi all_mailboxes endpoint palauttaa kaikki käyttäjän postilaatikot
- check_auth ja login palauttavat nyt myös user_id ja signatures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:09:30 +02:00
11e1103eb4 Siirrä yritysvalitsin header-yläpalkkiin nappien joukkoon
Dropdown siirretty header-left → header-right, kompaktimpi nappikoko
headerissa, flex-wrap tukee kapeampia näyttöjä.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:46:49 +02:00
44e401f4d3 Make API key and CORS settings per-company
- saatavuus endpoint finds company by API key, searches only that company
- config/config_update/generate_api_key now use company config
- API tab shows active company name
- Each company has own api_key and cors_origins in their config.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:39:35 +02:00
92d52f34ad Add ticket sorting by status priority, updated, or created date
Default sort: status priority (käsittelyssä → uusi → odottaa → suljettu)
then by updated date within same status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:37:31 +02:00
64ff8eaa91 Fix company access: sync session from users.json on every check_auth
- check_auth always reads fresh company permissions from users.json
- user_update updates session immediately when editing own permissions
- Prevents stale session showing tickets from companies user lost access to

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:34:18 +02:00
9973485cb4 Remove temp diag endpoints, improve auto-recovery for companies.json
- Remove temporary data_diag/data_read/data_write endpoints
- Auto-recovery now scans existing company directories if companies.json
  is empty or missing (handles git deploy wiping the file)
- Auto-creates config.json for any company dir missing it

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:33:21 +02:00
443e8fcfc3 TEMP: Fix diag endpoint auth for production recovery
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:28:51 +02:00