IT · Internal
Ticket Foundry
Development changelog — all builds and updates
June 09, 2026
v1.05-pre / v1.06-pre — Security Hardening & IIS Fix
v1.06-pre
IIS redirect trailing slash — fully fixed FIX
All header() redirects across index.php, logout.php, settings.php, ticket.php, and auth.php were using app_url() which produced broken paths on IIS when SCRIPT_NAME returned / or empty string. Replaced every redirect with config('site_url') directly — no more IIS path manipulation possible.
Timing attack on cron key SECURITY
All three cron scripts were using !== for key comparison, vulnerable to timing attacks. Changed to hash_equals() on daily-report.php, monthly-report.php, and never-logged-in.php.
Viewer IDOR on ticket PATCH SECURITY
Viewers could PATCH any ticket by ID — the role check only stripped assigned_to but didn't prevent editing tickets they didn't submit. Now verifies the requester_email matches the viewer's session email before allowing any edits.
Department and location ID validation on ticket create SECURITY
department_id and location_id were accepted on ticket creation without verifying they exist as active records. Invalid IDs are now silently nulled before insert.
Kanban board fills viewport IMPROVEMENT
Board now fills the full page height — no dead space below columns when tickets are few. All four columns stretch to equal height via flex chain from page-body down through kanbanView to the board.
Projects OVERVIEW label added IMPROVEMENT
Projects page now shows the OVERVIEW label above the stats pills to match the Tickets board layout.
Upload size reads from config everywhere FIX
New Ticket modal and Projects attachment drop zone were hardcoded to 10MB. Both now read from config('max_upload_mb'). Server-side MAX_FILE_MB constant in api/attachments.php also reads from config.
Uploads Backup button style matched IMPROVEMENT
Uploads Backup button was btn-secondary while Database Backup was btn-primary. Both now btn-primary for consistency.
Path traversal hardening on attachments SECURITY
api/attachments.php added realpath() checks on both the file serve and delete endpoints to prevent path traversal. Flagged by Akido security scan.
Flask artifacts removed from repo FIX
app.py from the original Python/Flask prototype was still in the repository, triggering false positive security alerts. Removed.
June 04, 2026
v1.04-pre — Pagination, Projects Drag & Drop, UI Polish
v1.04-pre
List view pagination NEW
Ticket list view now paginates. Page size configurable in Settings → General: 25 / 50 / 100 / All. Defaults to 25. Pagination bar shows current range and total count. Filters and search reset to page 1 automatically.
Project kanban drag and drop NEW
Project cards can now be dragged between Planning, Active, On Hold, and Complete columns — same as the ticket board. Status updates automatically on drop via PATCH.
Submit Form moved to its own Settings tab IMPROVEMENT
External Ticket Submission settings moved out of General into a dedicated Submit Form tab. General tab is significantly less cluttered.
Save buttons and audit logging on Settings IMPROVEMENT
Tickets Per Page and Completed Projects Window cards now have explicit Save buttons. Audit log entries added for meaningful settings changes: company name, ticket format, notifications, email provider, and submit form enable/disable.
Done column scrolls independently IMPROVEMENT
Kanban board Done column now has a fixed height with its own scroll, so a long completed list doesn't push the other columns off screen.
Confirm before closing New Ticket and New Project modals IMPROVEMENT
Clicking the backdrop or ✕ while title or description has content now shows a "Discard changes?" confirmation. Prevents accidentally losing a ticket mid-entry.
Projects Overview label added IMPROVEMENT
Projects page now shows the OVERVIEW label above the stats pills to match the Tickets board layout.
Hide button removed from Tickets overview IMPROVEMENT
Removed the ▲ Hide button from the overview stats bar — not a commonly used feature and added visual noise.
Project notes API fixed FIX
api/notes.php was calling require_csrf_header() which doesn't exist — fixed to require_csrf(). Adding notes to projects was returning a 500.
Bulk actions JS missing FIX
updateBulkBar, toggleSelectAll, clearBulkSelection, bulkApply and handleRowClick functions were referenced but never inserted into dashboard.php. Checkboxes showed but nothing happened on click.
Bulk action bar display fix FIX
Bulk bar had display:none set twice in its inline style — JS was setting it to flex but the second declaration overrode it. Bar never appeared.
June 02, 2026
v1.03-pre — Quality of Life, Mobile & Notifications
v1.03-pre
Ticket aging indicators NEW
Tickets that haven't been updated in a while now show a colored age badge on both the kanban board and list view. Yellow ⚠ for warning threshold, red 🔴 for critical. Thresholds configurable in Settings → Notifications → Ticket Aging Alerts. Default: warning at 3 days, critical at 7 days.
Bulk ticket actions NEW
Checkboxes in list view allow selecting multiple tickets. A bulk action bar appears with dropdowns to set status, priority, or assigned tech across all selected tickets at once. Select All in the header grabs everything. Hidden on mobile.
Requester status notifications NEW
Single on/off toggle in Settings → Notifications. When enabled, emails the requester when their ticket status changes to In Progress, Waiting, Done, or Reopened. Requires a valid requester email on the ticket.
Search includes notes and comments IMPROVEMENT
Ticket search now searches comment/note body text in addition to title, description, ticket number, and requester name.
Completed projects window — Settings → General NEW
Configurable dropdown (7 / 30 / 60 / 90 days / All time) controls how long completed projects appear in the Projects page, Projects report, and the projects section of Daily, Weekly, and Monthly reports. Previously completed projects showed indefinitely.
External Ticket Submission moved to General IMPROVEMENT
External Ticket Submission settings moved from Notifications tab to General tab where it makes more sense as a global configuration option.
Mobile — Settings/Reports/Audit hidden from nav IMPROVEMENT
Settings, Reports, and Audit Log links hidden from the mobile sidebar. These pages aren't optimised for mobile and the links were taking up space that's better used for tickets and projects.
Mobile — Projects defaults to list view IMPROVEMENT
Projects page now defaults to list view on mobile screens. Kanban columns are too cramped on small screens — list view is much more usable. Board view still available via the toggle button.
Mobile — modal tap-through fixed FIX
Tapping ticket cards was occasionally triggering the New Ticket modal on mobile. Root cause: modal overlays were using opacity:0 + pointer-events:none when closed, which some mobile browsers still treated as tappable. Changed to display:none so closed modals are completely removed from hit-testing.
Remember me cookie fix FIX
The 30-day remember me cookie was being set with Secure flag hardcoded to true, causing browsers to silently drop it on HTTP connections. Now detects HTTPS properly and sets the flag accordingly. Also added the cookie check to index.php on page load.
Settings tab structure repaired FIX
Moving the External Ticket Submission card introduced a missing closing div that caused all Settings panels after General to be nested inside the General panel — appearing as blank tabs. Fixed div structure and added missing backup tab to can_see_settings_tab() auth check.
May 27, 2026
v1.02-pre — Backup, UI Polish & Email Fixes
v1.02-pre
Database & uploads backup NEW
New Backup tab in Settings. One-click download of a full SQL dump — all tickets, users, settings, comments, attachment metadata. Second button downloads a zip of the uploads/ folder. Requires ZipArchive PHP extension for uploads backup.
API key field name mismatch fixed FIX
Settings was saving the API key as email_api_key but mailer.php looked for postmark_api_key (and sendgrid_api_key etc). API email worked on initial setup but broke after re-saving settings. Now saves under the correct provider-specific key.
PHPMailer exception namespace fix FIX
send_via_phpmailer() was catching the base Exception class instead of PHPMailer\PHPMailer\Exception. On some servers the catch never fired, the exception bubbled up uncaught, and the API returned a 500. Fixed to catch the correct namespaced exception plus a Throwable fallback.
SMTP errors now surface properly IMPROVEMENT
SMTP/API failures now return the actual error message in the toast — authentication failure, connection refused, bad API key etc — instead of a generic "Request Failed".
Sidebar and topbar header alignment IMPROVEMENT
Sidebar logo section and topbar were different heights causing the horizontal divider lines to not align. Both set to a fixed 64px height with flex centering.
Theme swatches resized IMPROVEMENT
Default theme picker in Settings was taking up excessive space. Swatches reduced in height and reorganised into a compact 2-column grid with max-width constraint.
app-mobile.css created FIX
Every page was throwing a 404 for /assets/css/app-mobile.css — the file was referenced in layout_header.php but never existed. Mobile styles extracted from inline style block into a proper app-mobile.css file.
Version number in Settings NEW
Version number and build date now shown at the bottom of Settings → General with a link to the changelog.
May 27, 2026
v1.01-pre — Backup, SMTP Fix & Error Handling
v1.01-pre
Database & uploads backup NEW
New Backup tab in Settings. One-click download of a full SQL dump of the database — all tickets, users, settings, comments, attachment metadata. Second button downloads a zip of the uploads/ folder. Requires ZipArchive PHP extension for uploads backup. CSRF-protected GET download endpoint.
PHPMailer exception namespace fix FIX
send_via_phpmailer() was catching the base Exception class instead of PHPMailer\PHPMailer\Exception. On some servers (notably IIS) the catch block never fired, the exception bubbled up uncaught, and the API returned a 500 with no error detail. Fixed to catch the correct namespaced exception plus a Throwable fallback.
SMTP error messages surfaced properly IMPROVEMENT
SMTP failures now return the actual PHPMailer error message (authentication failure, connection refused, etc.) instead of a generic "Request Failed". Decrypt failures return a specific message. Empty password after decryption returns a specific message.
May 21–26, 2026
v1.0 Final Release — Install Testing & Production Hardening
v1.0
v1.0 Final Release NEW
First production-ready release. Packaged as ticket-foundry-v1.0.zip — clean install, no setup artifacts, LICENSE.txt included, install guide redirects to ticketfoundry.net for always-current docs.
Schema table ordering fixed FIX
tf_tickets has a foreign key to tf_locations, and tf_attachments has a foreign key to tf_projects — but both referenced tables were defined later in schema.sql. MySQL silently failed to create tf_tickets, tf_comments, and tf_attachments on fresh installs. Fixed table creation order so all foreign key dependencies are satisfied.
tf_password_resets missing columns FIX
Schema was missing used and ip_address columns on tf_password_resets. Forgot Password page threw a 500 on any fresh install. Both columns added to schema.
PHPMailer path case sensitivity FIX
mailer.php was requiring /includes/phpmailer/ (lowercase) but the folder is /includes/PHPMailer/ (uppercase). On Linux filesystems this is case-sensitive — PHPMailer was never found, silently fell back to PHP mail(), which failed. All four require_once paths corrected to match actual folder name.
Report tabs renamed IMPROVEMENT
7-Day Report → Weekly Report, 30-Day Report → Monthly Report. Clearer labelling throughout the Reports page.
Custom email subjects on scheduled reports NEW
Each report schedule (Daily, Weekly, Monthly) now has a customisable Email Subject field. Supports {company} and {date} placeholders. Defaults to sensible values, saves to config, substituted at send time in cron scripts.
Send time on Weekly and Monthly reports NEW
Weekly and Monthly report schedules previously only had a day picker with no time. Time picker added to both, defaulting to 08:00. Cron scripts read the configured time and exit silently if it's not the right hour.
Category inline edit on ticket modal NEW
Category was read-only in the ticket modal — no way to change it after creation. Now a dropdown matching the status and priority selectors. Changes save instantly via updateTicketField(). Viewers still see it as read-only text.
Ticket note HTML not rendering FIX
Notes on the direct ticket page (ticket.php) were displaying raw HTML tags instead of rendered content. Quill stores notes as HTML — the template was using htmlspecialchars() which escaped the tags. Fixed to output raw HTML.
Ticket note author showing username not full name FIX
Comments query on ticket.php was selecting u.username instead of COALESCE(u.full_name, u.username). Fixed to show display name consistently.
All 10 themes in My Profile FIX
profile.php was only listing 6 themes — missing Midnight, Light, Warm, and High Contrast. All 10 themes now available in the profile theme picker.
Never-logged-in reminder cron hardened IMPROVEMENT
Added try/catch with verbose output to never-logged-in.php. Previously silent failures showed Done. Sent: 0 with no indication of what went wrong. Now prints per-user status and any exception messages directly in the response.
LICENSE.txt added NEW
Commercial use license included in the package. One purchase = one install. No redistribution, reselling, or sublicensing. PHPMailer LGPL license also included in includes/PHPMailer/LICENSE.
Install guide updated — no Beta, full dependency tables IMPROVEMENT
All Beta wording removed. Before You Begin section rebuilt with separate dependency tables for PHP extensions, Apache, IIS, and Nginx. Step 3 (Schema Import) updated to reflect automatic import via setup wizard — manual phpMyAdmin fallback moved to a collapsible details block.
May 14–19, 2026
Beta Release — Distribution, New Features & Bug Fixes
v0.5 Beta
Reformat ticket numbers preserves updated_at FIX
The reformat query was triggering MySQL's ON UPDATE CURRENT_TIMESTAMP on the updated_at column, stamping every ticket with the exact moment the reformat ran. This skewed Average Resolve Time in reports to show absurd numbers (20+ days) for old tickets. Fixed by explicitly setting updated_at = updated_at in the UPDATE statement to bypass the auto-update trigger.
Reformat existing ticket numbers NEW
Added "Reformat All Ticket Numbers" button in Settings → General → Ticket Number Format. Rewrites all existing ticket numbers to match the current prefix/date/padding configuration using each ticket's original created_at date. Useful when migrating from an old format (e.g. TF-0001) to the new format (EPI-20260520-00085). Logs to audit log. Cannot be undone.
Removed redundant sort dropdown IMPROVEMENT
Removed the "Newest First / Oldest First / By Priority" dropdown from the list view filter bar. Column headers already handle sorting by clicking — the dropdown was redundant and added clutter.
Category field on tickets fixed FIX
Category column in tf_tickets was defined as ENUM, silently rejecting any new categories added after install and falling back to 'Other'. Altered to VARCHAR(100). Category dropdown added to ticket modal so category can be changed inline like status and priority. catIcon() function was undefined — now built from a live CAT_MAP loaded from tf_categories at page load so new categories show their icons automatically.
Self-contained setup wizard NEW
Completely rewritten setup.php — zero dependencies on auth.php or db.php. Reads DB credentials via regex, handles schema import, admin account creation, site settings, ticket number format, email config, and generates encryption key on finish. Works on Apache, IIS, and Nginx.
IIS / Windows Server support NEW
Added web.config as full IIS equivalent of .htaccess — URL rewriting, security headers, blocked paths. Also added nginx.conf.example for Nginx installs. Ticket Foundry now officially supports Apache, IIS, and Nginx on any OS.
Interactive installation guide NEW
install-guide.html — single HTML file covering prerequisites, step-by-step setup, all email providers, cron job setup, server types (Apache/IIS/Nginx/Raspberry Pi), internal DNS, troubleshooting, and security recommendations.
Schema completed — 19 tables IMPROVEMENT
Added missing tables: tf_locations (with address/city/state/zip), tf_categories, tf_directory, tf_password_resets, tf_remember_tokens, tf_templates, tf_project_checklist, tf_project_attachments. Fixed tf_tickets: added location_id, source, VARCHAR category. ticket_number expanded to VARCHAR(40).
Internal notes NEW
Notes can now be marked Internal Only — skips email notification to requester and is hidden from viewer accounts. Displayed with purple indicator in the note thread. is_internal column added to tf_comments.
Clickable overview pills NEW
Urgent, New, In Progress, Waiting, Total Open, and Completed 7-Day pills are now clickable filters. Click to filter the board, click again to clear. Active pill highlights with acid green label.
Assigned Tech filter NEW
New dropdown in the filter bar lets admins and techs filter tickets by assigned tech, including an Unassigned option. Auto-populated from active staff accounts.
Location field on tickets NEW
Location dropdown added to ticket detail modal. Techs/admins can change it inline. Viewers see it as read-only text.
Category drag-to-reorder NEW
Categories in Settings → Organization can be reordered by dragging. Order persists to DB and reflects immediately in all dropdowns.
Emoji picker for categories NEW
Category icon field replaced with a click-to-open emoji grid — 64 IT-relevant emojis across 8 categories. Click the icon preview to open, click any emoji to select.
Templates category dropdown from DB FIX
Template category dropdown was hardcoded. Now loads live from tf_categories so new categories appear automatically.
Configurable file upload size limit NEW
Settings → General now includes a Max Attachment Size dropdown (2/5/10/20/50MB). Shows server PHP limits inline so admins know the ceiling. All attachment upload areas read from config.
10 themes NEW
Added Light, Midnight, Warm, and High Contrast themes. All 10 themes available in both Settings → General and My Profile. Theme switcher whitelist updated to include all options.
Credentials encrypted at rest IMPROVEMENT
Setup wizard generates a unique AES-256 encryption key on finish and writes it to tf_config.php. SMTP passwords and all API keys (Mailgun, Postmark, SendGrid, Brevo) are encrypted before being stored in tf_config table.
Email stored in session IMPROVEMENT
User email now stored in session on login, enabling viewer ticket filtering by requester_email.
Viewers now see their own submitted tickets FIX
Viewers were previously filtered by assigned_to which showed nothing since tickets aren't assigned to requesters. Now filters by requester_email so viewers see all tickets they submitted.
Email provider routing fixed FIX
mailer.php was only routing to API when email_method === 'api'. Named providers (mailgun, postmark, sendgrid, brevo) now correctly route to send_via_api(). Provider-specific API key lookup fixed.
Email failures no longer crash ticket creation FIX
All notify calls wrapped in try/catch. Email failures logged to PHP error_log and audit_log (action: email.error) but don't prevent ticket/comment creation.
Ticket number generation fixed for MySQL 5.7 FIX
REGEXP_REPLACE used for ticket number generation is MySQL 8.0+ only. Replaced with COUNT(*) + preg_match on last ticket number — works on all MySQL/MariaDB versions. Fixed in both api/tickets.php and submit.php.
Public submit form improvements IMPROVEMENT
Added source column to tickets (web_form vs internal). Fixed duplicate ticket number bug. Try/catch on insert returns friendly error instead of fatal. Ticket number VARCHAR expanded to 40 chars.
Interactive user guide NEW
user-guide.html — complete user documentation with light/dark toggle, role-based content filtering (Admin/Tech/Viewer), live demo widgets for the ticket board, new ticket form, status updates, and theme picker. Searchable, collapsible FAQ.
May 08–18, 2026
Sandbox Build — sandbox.ticketfoundry.net
v1.0 Sandbox
Full sandbox environment NEW
Standalone PHP/MySQL sandbox app hosted at sandbox.ticketfoundry.net. Separate DB instance (tf_sandbox), no login required, built as a live interactive demo of the full product. Multiple sessions across two weeks to get it production-ready.
No-login role switcher NEW
Sidebar role switcher lets visitors flip between Admin, Tech, Manager, and End User views without creating an account. Each role shows exactly what a real user in that role would see — different nav, different permissions, different ticket visibility.
7-day auto-reset via cron NEW
Cron job wipes and re-seeds the sandbox DB every 7 days automatically. Manual reset.php available — upload it, hit the URL with the secret key, everything resets, delete the file. Prevents the sandbox from accumulating garbage indefinitely.
Word filter middleware NEW
All user-submitted content passes through filter.php before hitting the DB. Catches slurs, profanity, and other obvious abuse. Because that's how people on the internet are.
Pre-seeded demo data NEW
Sandbox launches with realistic seed tickets, projects, and users. Includes the classics: "Printer has chosen violence again", "It worked yesterday", and "Replace the spreadsheet pretending to be a system". Restores to this state on every reset.
Settings visible, non-saving NEW
Full settings panel is visible so visitors can explore every configuration option — but nothing persists. Company name locked to "Ticket Foundry Sandbox". All 10 themes available and switchable per-session.
Static audit log NEW
Audit log page shows realistic fake entries rather than real activity. Demonstrates the feature without exposing actual sandbox usage data or building up a real log that gets wiped on reset.
PDF-only reports NEW
Reports generate and download as PDF normally. All email send buttons replaced with "Emails disabled for sandbox" message. No outbound email from the sandbox environment.
File upload UI disabled NEW
Attachment drag-drop area visible but non-functional. Upload endpoint returns a polite rejection. The placeholder UI is there so visitors can see the feature exists without opening a file upload endpoint to the public internet.
Security hardening IMPROVEMENT
.htaccess blocks direct access to /includes, .sql files, and reset.php by default. TF_SANDBOX constant guards all include files — direct HTTP requests to includes/ return 403. Relative path includes throughout for portability.
May 12, 2026
Modals, Bug Fixes, UX Polish
v0.4
New Ticket Modal
Global New Ticket modal NEW
New Ticket now opens as a modal overlay from any page in the app — Reports, Settings, Projects, wherever. No longer navigates away. Stays on current page after submit.
Board auto-refresh on submit IMPROVEMENT
If you're on the dashboard when you log a ticket, the board reloads automatically. On any other page it just shows a toast and closes.
Removed New Ticket from sidebar IMPROVEMENT
Redundant nav link removed. The modal button in the topbar is the single entry point. new-ticket.php standalone page still accessible via direct URL.
Categories
DB-backed ticket categories NEW
Categories are now fully managed in Settings → Organization → Categories. Add/edit/reorder with emoji icons. All dropdowns (New Ticket, dashboard filter, custom report) load from the database.
Real-time category refresh IMPROVEMENT
Saving category changes broadcasts via localStorage so other open tabs update their dropdowns without a reload.
Settings Restructure
Settings tabs reorganized IMPROVEMENT
5 top-level tabs: General, Email, Organization, Accounts, Templates. Organization has sub-nav: Departments / Locations / Categories / User Directory. Accounts is standalone since it's about system access not org structure.
Settings hidden from Tech role IMPROVEMENT
Settings nav link now only shows for Admin and Superuser. Techs had no accessible tabs in there anyway.
Reports
Custom report email uses same engine as preview IMPROVEMENT
Previously the email was rebuilt from scratch and was missing stats. Now uses TFReports::monthly() — same engine as the preview — so resolution rate, avg resolve time, and all breakdowns match exactly.
Ticket links toggle on scheduled reports NEW
Each report panel (Daily, 7-Day, 30-Day) has an "Include ticket links" toggle that saves per-report to config.
Standalone Ticket Page
ticket.php — direct ticket URL NEW
/ticket.php?id=X gives a standalone page for any ticket. Used in email notification links. Techs can add notes directly. Viewers see only their own tickets.
Email notifications link directly to ticket IMPROVEMENT
All notification emails now link to /ticket.php?id=X instead of the dashboard. Includes ticket description in the assigned email (truncated at 300 chars).
Bug Fixes
Attachments not saving on new ticket creation FIX
new-ticket.php was generating a CSRF token under a different session key than the one attachments.php validates. Files uploaded fine but silently 403'd. Both now use csrf_token().
Custom report email missing data FIX
Resolution rate was blank, avg resolve time showed just "D", full ticket list was missing. Caused by the send handler building its own data instead of using the report engine.
JSON parse error on report send FIX
Leftover debug echo "Step C: csrf/admin OK" was leaking into the JSON response. Removed.
Drag-and-drop ghost card staying on board FIX
After dragging a ticket to a new column the card wasn't disappearing from its old column. Drop handler was calling loadStats() instead of loadTickets().
Completed tickets not hiding from kanban after 7 days FIX
done_7d=1 param was already being sent but confirmed working. Older tickets showing were a migration artifact from May 5th work bumping their updated_at — resolved naturally May 12-13.
note_added_to_tech email causing 500 on reports load FIX
mailer.php referenced $ticket_url in the note-added handler without defining it first.
May 05, 2026
Email, Reports, Security
v0.3
Email System
SMTP vs API email method toggle NEW
Settings → Email tab now supports both SMTP and HTTP API modes. Bypasses Dreamhost mail interception entirely via HTTPS calls.
Multi-provider API support NEW
Postmark, SendGrid, Mailgun, and Brevo all supported. Each provider has correct auth headers, payload structure, and a hint for where to find the API key.
Renamed SMTP tab to Email IMPROVEMENT
Reflects that the tab now covers both SMTP and API configuration.
Password Reset flow NEW
Forgot Password link on login page. Secure token emailed, expires in 1 hour. Password strength meter on reset page. Tokens are single-use and hashed in the DB.
Welcome / invitation email NEW
New user creation sends a branded Ticket Foundry welcome email with a 24-hour setup link. No temp password in the email body to avoid spam filters.
7-day never-logged-in reminder cron NEW
Sends a nudge email to users created 7+ days ago who haven't logged in. Toggle in Settings → Notifications. Runs via daily cron job.
Security
Rate limiting on password reset SECURITY
Max 3 reset requests per IP per 15 minutes. Prevents automated hammering of the forgot password endpoint.
Token hashing SECURITY
Raw token sent in email URL, SHA-256 hash stored in database. Tokens in DB are useless without the original.
IP address logging on reset requests SECURITY
Every password reset request logs the requester's IP to tf_password_resets and the audit log.
Updated .htaccess SECURITY
Added dotfiles block, removed redundant directives, tightened log file blocking. Cron directory unblocked to allow scheduled jobs.
Reports
Custom Report tab NEW
Date range picker with filters for status, priority, category, and assignee. Summary and Full Report modes. CSV export. Defaults to last 30 days.
Who's Submitting breakdown NEW
Ranked requester leaderboard with bar indicators, by department, and by location. Added to Custom Report and 30-Day email template.
Report settings no longer overwrite each other FIX
Saving one report tab was blanking out the other tabs' settings. Fixed to only update keys that were actually submitted.
Summary/Full toggle now persists FIX
Report type selection is saved to config and restored on page load.
CSRF token fix on report saves and custom report FIX
Reports page was looking for a meta tag that didn't exist. Now uses PHP-injected CSRF variable.
Daily cron now uses app timezone FIX
Was using server (Pacific) time instead of configured app timezone (Central). Hour check now respects the configured timezone.
User Accounts
Disabled accounts greyed out with inline actions NEW
Inactive accounts show at 45% opacity with a disabled badge. Reactivate and Delete buttons appear inline instead of the Edit button.
Invite toggle on new user creation NEW
Styled toggle card replaces the old checkbox. When on, temp password field is hidden and a setup link is emailed instead.
admin account excluded from all Assign To dropdowns SECURITY
The superuser admin account no longer appears in any ticket or project assignment dropdowns.
Bug Fixes
Department dropdown auto-refresh FIX
Adding or editing a department now broadcasts a refresh signal via localStorage. Other open tabs pick it up and update their dropdowns automatically.
tfDate race condition on login FIX
app.js now loads in the head with defer, guaranteeing it's parsed before any inline scripts run.
Reactivate user passing null ID FIX
Duplicate function definition was overriding the one with the id parameter, causing all reactivation calls to send id=null.
Password reset 500 error FIX
auth.php was not included in reset-password.php and forgot-password.php, causing fatal errors on audit_log calls.
May 04, 2026
Locations, Reports, Demo
v0.2
Locations Feature
Locations management tab NEW
Settings → Locations — add/edit office locations with name, address, city, state, zip. Enable/disable. Accessible to admin and superuser.
Location on User Directory profiles NEW
Location dropdown added to each directory user. Saved to their profile and auto-fills on New Ticket.
Location on tickets NEW
Location dropdown on New Ticket form next to Department. Auto-fills from directory. Editable dropdown in ticket modal. Shows on kanban cards as Category · Requester · Location.
Backfill SQL migrations NEW
SQL queries to backfill location_id and department_id on existing tickets by matching requester email to directory records.
Reports
Audit log CSV export respects filters IMPROVEMENT
Export CSV button exports only the currently filtered results, not the full log.
Audit log CSV exporting raw text FIX
CSV handler was running after HTML had already been sent. Moved before layout_header.php include.
Dashboard & Tickets
Sidebar filter shortcuts restored NEW
New / In Progress / Waiting / Completed under Tickets. Planning / Active / On Hold / Complete under Projects. Indented under All Tickets and All Projects.
Ticket Templates NEW
Configure templates in Settings → Templates (admin/superuser). Template bar on New Ticket form for techs. Applies title, description, priority, category with [BRACKET] placeholders. ✕ Clear button.
Demo Site
Full demo rebuild NEW
Complete rewrite of demo.html to match all current features. Sidebar filters, location on cards, 4 templates, project checklists, 6 themes.
Silly seed data IMPROVEMENT
Gary Noonan, Bev Butterworth, Wanda Crumble, Bob Honksworth, Randy Potts, Dolores Fink, Chuck Plunkett. Bob gets the Power Rangers ticket and fails security training twice.
Web Dude easter egg NEW
webdude@thewebsiteisdown.com assigned to Chip Hendricks' failing hard drive ticket. Notes include instructions to hold it like a sandwich.
Bug Fixes
Settings tab SyntaxError crashing all tabs FIX
openNewDirModal was using await without being declared async. One-word fix that unblocked all settings tab navigation.
Location dropdown empty on user edit FIX
openEditDirModal was setting the dropdown value before the options existed. Now fetches and builds options first.
New Template button not working FIX
openTemplateForm, editTemplate, and cancelTemplateForm were accidentally deleted during location feature edits. Restored.
May 01, 2026
Initial Build
v0.1
Core System
Full application scaffold NEW
PHP/MySQL app on Dreamhost shared hosting. tf_config.php, db.php, auth.php, mailer.php, layout_header/footer. Session management, CSRF protection, bcrypt passwords.
4-role access control system NEW
Viewer, Tech, Superuser, Admin. Role-based sidebar nav, tab visibility, assignment rules, and feature gating throughout.
MySQL timezone sync NEW
Fixes Dreamhost Pacific vs configured timezone issue. Sets MySQL session timezone on every PDO connection.
Tickets
Kanban + list view dashboard NEW
4-column kanban (New / In Progress / Waiting / Completed) with drag-and-drop. List view toggle. Stats row. 60-second auto-refresh. Filters for search, status, priority, My Tickets.
Ticket modal NEW
Full ticket detail with inline editable status, priority, assigned, location. Rich text notes via Quill. File attachments with drag-drop. Edit title, description, requester info inline.
New Ticket form — dual experience NEW
Techs get full form with all fields. Viewers get auto-filled requester info, no priority/category/assign. Directory lookup auto-fills department and location.
Ticket numbering NEW
TF-XXXX sequential numbering. Auto-increments from highest existing number.
Projects
Projects kanban + list view NEW
4-column kanban (Planning / Active / On Hold / Complete). List view with progress bars. My Projects filter. Single assignee dropdown.
Project checklists NEW
Add/check/delete checklist items. Progress bar and ✓ X/Y indicator on cards. Drag-to-reorder.
Rich text notes and file attachments NEW
Quill editor for project notes. File attachments with drag-drop upload.
Settings
Multi-tab settings panel NEW
Site Settings, Email, Notifications, Departments, Locations, User Directory, User Accounts, Templates. Each tab role-gated.
6 themes NEW
Dark Foundry, Midnight, Light, Forest, Crimson, Slate. User preference saved per-account.
Show Timestamps toggle NEW
Toggle timestamps on/off across the app. When on, shows MM-DD-YYYY h:MM AM/PM format.
Reports & Audit
Daily, 7-day, 30-day reports NEW
Summary and Full Report modes. Schedule sending with day/time/recipient config. Send Now button. PDF export via print dialog.
Audit log viewer NEW
Full system action log with filters (search, action type, user, period), pagination at 50/page, and CSV export. Export respects active filters.
Marketing Site
Interactive demo site NEW
Fully client-side demo with all features, 6 themes, silly seed data, and easter eggs. No backend required.
Apr 30 – May 01, 2026
PHP Rewrite & Deployment
v0.1.2
Platform Migration
Full rewrite from Python/Flask to PHP/MySQL NEW
Dreamhost shared hosting doesn't support Python WSGI apps. Entire codebase rewritten in PHP with PDO/MySQL. Same feature set, production-ready on shared hosting.
Dreamhost deployment and DNS config NEW
Subdomain setup, web root config, MySQL provisioning, PHP session handling, file permissions. Several rounds of debugging PHP errors and 500s on first deploy.
Setup wizard NEW
First-run setup wizard creates admin account, sets company name, site URL, and timezone. Locked after completion.
Core Features (PHP)
Authentication system NEW
Session-based auth, bcrypt passwords, login attempt tracking with lockout, must_reset_password flag, CSRF tokens on all forms.
Kanban board NEW
Drag-and-drop kanban with 4 columns. List view toggle. Ticket modal with full detail, notes (Quill), file attachments.
Projects board NEW
Kanban and list view for long-term projects. Notes, attachments, progress tracking.
6 themes NEW
Dark Foundry, Midnight, Light, Forest, Crimson, Slate. CSS variable-based theming.
Daily, 7-day, 30-day email reports NEW
HTML email templates for all three periods. Schedule config, Send Now, cron scripts.
Settings panel NEW
Multi-tab settings with site config, SMTP, notifications, departments, user directory, user accounts.
Apr 29, 2026
Sessions 2–3 — Python/Flask MVP expansion
v0.1.1
Flask App (pre-PHP)
Tech/user model and role system NEW
Added Tech model to Flask app. Role-based access control groundwork that carried over to the PHP rewrite.
Ticket assignment and status workflow NEW
Assign tickets to techs. Status transitions: New → In Progress → Waiting on User → Done.
Comments and notes system NEW
Threaded comments on tickets. Internal notes visible to techs only.
File attachments NEW
Upload and attach files to tickets. Stored in uploads/ directory.
Projects module NEW
Long-term project tracking separate from tickets. Kanban board, status, notes.
Apr 27, 2026
Initial concept & Python/Flask MVP
v0.1.0
Origin
Concept: replace Microsoft Planner with a real ticketing system NEW
"I want to build a lightweight internal IT ticketing web app as a replacement for using Microsoft Planner as a fake ticket system." — the prompt that started it all.
Python/Flask MVP — TicketTrack NEW
Initial build as a Python/Flask app named TicketTrack. SQLite database, basic ticket CRUD, login system, dark theme UI.
Renamed to Ticket Foundry IMPROVEMENT
TicketTrack → Ticket Foundry. Better name, better brand.
Dark UI with Space Grotesk + Space Mono NEW
Established the core design language — dark foundry aesthetic, acid green accent, monospace for meta info. Carried through to every version since.