πŸš€ v5.19

This changelog provides a detailed overview of technical changes, including new features, bug fixes, and maintenance updates. It is intended for developers, DevOps engineers, and technical teams to track system improvements and API modifications.

Each update is categorized into:

  • ✨ Added – New features and functionality improvements
  • πŸ› οΈ Fixed – Bug fixes and stability enhancements
  • πŸ”§ Chore – Code refactoring, performance optimizations, and internal updates
  • ⚠️ Breaking change – Changes that modify existing system behavior or require adjustments in configuration, calculations, templates, or integrations


πŸ“¦ [5.19.3] - 2026-09-09

✨ Added

  • tas-3652 OAuth 2.1 authorization server ✨ ⚠️ Breaking change:
    Note: TAS is now an OAuth 2.1 authorization server, so MCP clients that require OAuth (Claude, ChatGPT) can connect without a manually issued static token, and any integration can obtain short-lived access tokens instead of a long-lived secret. Two grant types share the new /oauth/token endpoint: the authorization-code flow with mandatory PKCE for user-scoped access (the user logs in through any configured authority and approves the connection on a new consent screen), and the client-credentials flow for machine access, where an administrator creates a confidential client paired to a system user. OAuth access tokens act as the user everywhere a normal session token does, and the /mcp endpoints accept them alongside API tokens. Users see and revoke their own connections in "Connected applications" in user settings; administrators see and revoke every issued grant. Refresh tokens rotate on every use with reuse detection, and any revocation cuts off all outstanding access tokens within a minute. The administration menu entry "API Tokens" is replaced by "API Access" (/administration/api-access) with three tabs – API tokens, OAuth clients, OAuth grants. Existing static B2B API tokens are unchanged and keep working. No deployment change is required; dynamic client registration ships disabled and can be enabled with TAS_OAUTH_DYNAMIC_CLIENT_REGISTRATION. Requires the migration adding the AUTH_OAUTH_CLIENT and AUTH_OAUTH_GRANT tables.

  • tas-3652 OAuth discovery on path-prefixed deployments ✨
    Note: OAuth discovery also works on deployments where the backend is proxied under a path (issuer such as https://host/api). Because OAuth clients insert the well-known segment between host and path, the backend now serves the root-insertion forms of all three well-known documents and the frontend relays them, so discovery answers identically on both origins. No deployment step is required.

  • tas-3818 OAuth client detail, edit and permanent delete ✨
    Note: A registered OAuth client can be opened for inspection – name, type, client id and the exact registered redirect URIs, each with a copy button. A client's name and, for a public client, its redirect URIs can be changed after creation, so a mistyped callback no longer means deleting the client and reconfiguring the connected application. The client type and the paired system user stay immutable – they are the client's identity. A client can also be removed for good (superadministrators only); Disable remains the reversible action and now carries a lock icon, so the trash icon means only the irreversible one.

  • tas-3818 OAuth interoperability improvements ✨
    Note: Improved interoperability with OAuth clients whose discovery differs from Claude's. Every /mcp method answers an unauthenticated request with the RFC 9728 WWW-Authenticate challenge. An omitted code_challenge_method is taken as S256. The authorization server metadata advertises authorization_response_iss_parameter_supported, with iss carried on error and consent-denied responses too. Refused /authorize requests are logged with the client id, redirect URI and reason.

  • tas-3698 Accent-insensitive filtering on PostgreSQL ✨ ⚠️ Breaking change:
    Note: Accent-insensitive (diacritics-agnostic) filtering via disableAccentSensitivity is now supported on PostgreSQL and is honoured consistently across the task list, case list, DMS file list, custom-view raw filters and every paginated administration grid (roles, headers, crons, scripts, licences, vault, API tokens, mobile devices, HR logs, AI observability). Upgrade note: the PostgreSQL migration creates the unaccent extension and requires the database user to hold CREATE on the database or ownership of it; otherwise have a DBA run CREATE EXTENSION unaccent; once. The System Health page's Database component carries a new Accent folding metric and warns, with the statement to run, when the flag is on without the extension. With the flag on, PostgreSQL filtering costs roughly 1.6x a plain comparison; with the flag off (the default) nothing changes.

  • tas-3653 Cron import / export ✨
    Note: A cron's whole definition can be exported and imported as JSON from the cron detail page, the same way as an authentication method. The new "Import / Export" button shows the current settings (technical name, name, description, timing, active flag and parameters) as JSON for copying, and pasted JSON is applied onto the form, where it can be reviewed and saved as usual. Intended for moving a cron configuration between environments. An import carrying the technical name of a different cron is refused. The export contains cron parameters verbatim, including password-format values, so it should be handled with the same care as any other credential.

  • tas-3489 Translated smart-event picker and configuration forms ✨
    Note: The template-task smart event picker shows a translated business name and a one-line description for each smart event instead of the raw technical identifier (e.g. "HTTP Request" instead of SmartEventHttpRequester). The event's configuration form is translated too – field labels and field help texts now come from the locale files. Covers the 12 core and plugin events in all 11 languages. An event or field without translations renders exactly as before.

  • tas-3726 New calculation functions storage.copyDmsFilesToCase / storage.copyDmsFilesFromCase ✨
    Note: Physically copy DMS documents between cases and return the new documents' ids, using the same selectors as the existing move functions (file id, file name, attachment variable, or all case documents). Each selected document's current revision is stored into the target case as a new document with upload semantics – main/sub visibility recomputed, DMS attributes rebuilt, content parsed and fulltext-indexed again. A document of the same name already in the target case receives the copy as its next revision. The source case is left completely untouched. Unlike the move functions, copying requires a logged-in user context, and only the current revision is copied.

  • tas-3804 Dynamic rows - table-level minColWidth ✨
    Note: A new minColWidth setting in the tableDefinition table section overrides the default 70px column minimum for every column of the table. It applies to width clamping, the percentage-to-pixel conversion base on mobile, the scroll wrapper and the drag-resize lower limit, and can be changed at runtime via changeDef(). A missing or invalid value falls back to 70, so existing tables are untouched.

  • tas-3663 ISDOC plugin - raw XML output ✨
    Note: isDoc.extract and the IsDocSmartEvent can now return each invoice as the original ISDOC XML instead of parsed data, via the new third argument format ('json' by default, 'xml' for the raw XML string; the smart event gains a matching Invoice format option). This lets a script feed the XML through its own parser and get the same structure whether the invoice arrived as a plain .isdoc, an .isdocx container or a PDF attachment. Requires the plugin to be rebuilt/reinstalled (manifest 2.1.1).

  • tas-3715 AI conversations use scoped database transactions ✨ ⚠️ Breaking change:
    Note: An AI turn no longer holds a pooled database connection and row locks for the whole turn, which for a template-builder run can be several minutes. Transactions are scoped to the units that need atomicity: each write-tool invocation runs in its own transaction, the template import commits at import time, and everything else commits at its own flush. A failed turn therefore keeps the user message and the telemetry. A second message into a conversation whose turn is still running is rejected fail-fast with HTTP 409 and the "there is an action to complete, please wait" alert. The default of TAS_AI_TIMEOUT rises from 120 s to 600 s, so a long template-builder run completes within its own timeout. A turn that fails after the user message was stored replies with a persisted fallback message; when something had already been written, the reply says the changes made so far were saved and asks the user to review them.

πŸš€ Performance

  • tas-3870 Case event list is constant-cost for normal users πŸš€
    Note: The event list of a case (the events modal opened from a task or a case, and the manual-event list behind it) loads the process variable list once per process and resolves solver membership in the database instead of in memory, so its cost no longer grows with the number of waiting events or with the size of the user table. Behaviour change on one path: a waiting event whose reference user is empty or supervisor() is now narrowed by the template task's role/org-unit solver filters, the same way they already narrow the Permissions β†’ Events tab. On a template task that defines no solver filter (the default) the result is unchanged.

πŸ› οΈ Fixed

  • tas-3870 Permissions β†’ Events tab and waiting-event solver resolution πŸ› οΈ
    Note: The Permissions β†’ Events tab of a case detail loads on both database engines for cases carrying a waiting event, and its task-name column falls back to the instance-task name on installations whose template tasks carry no language mutation. The reference-user calculation of a waiting event is evaluated again, so the possible-users list of the Events tab and the hand-event list reflect the configured reference user rather than the guarantor. Task and user names containing special characters are handled correctly.

  • tas-3835 Exporting an overview to XLSX / CSV ⚠️ Breaking change:
    Note: Exporting an overview containing a big-value, dynamic-list or multi-select column now completes on SQL Server for large result sets. The configured export ceilings are also enforced: XLSX is capped at featureFlag.maxExcelExportedRows (50000 by default) and CSV at featureFlag.maxCsvExportedRows (100000). An over-limit export is refused rather than truncated, and both grids warn before the export is even sent. An instance that relies on exporting more than that has to raise the setting. A failed export reports which export failed and why.

  • tas-3455 ai.processDocument() reports failures ⚠️ Breaking change:
    Note: The function now throws an exception naming the cause when a document name matches nothing in the case, when text extraction fails, or when the AI call errors. Previously such failures were recorded server-side only and the function resolved as if it had succeeded. A calculation written against the previous behaviour will start surfacing the error and should handle it.

  • tas-3881 Custom e-mail logo is shown again πŸ› οΈ
    Note: A custom email logo uploaded in Visual identity renders again in the header and footer of notification emails. An already uploaded logo starts rendering with no re-upload. Instances without an uploaded logo are untouched.

  • tas-3809 5.17 upgrade migration no longer aborts on orphaned rows πŸ› οΈ
    Note: The 5.17 migration adding the USERS foreign keys could stop half-applied on databases carrying orphaned deputy rows or a USER_ROLES.ORG_ID pointing at a deleted organization. All of these are now swept before their foreign keys are created, without manual cleanup, the USER_VICE primary key is dropped by the name the database actually carries (very old schemas have system-generated names), and several destructive DROP INDEX / drop constraint statements on the same upgrade path gained if exists guards. Only affects deployments that have not yet run the 5.17 migration.

  • tas-3823 Calculations using toString, valueOf etc. inside array callbacks transpile again πŸ› οΈ
    Note: A calculation naming an inherited Object.prototype member inside a filter / find / some / reduce / sort callback transpiles correctly. Because a variable update re-transpiles every calculation in the template process, one such calculation could previously block variable edits across that template process. Nothing has to be re-saved after the upgrade.

  • tas-3804 Dynamic rows on tablets ⚠️ Breaking change:
    Note: The mobile variant of dynamic rows (pixel widths, horizontal scroll, the "…" action column) switches by a 900px viewport breakpoint, re-evaluated live on resize and rotation, so tablets in landscape render the desktop layout with percentage widths honoured. On the mobile variant, percentage column widths keep their authored ratio and never drop below the column minimum. Intentional behaviour change: a desktop browser window narrower than 900px now renders the mobile variant.

  • tas-2816 Service operations - Roles section loads again πŸ› οΈ
    Note: The section now loads for users whose saved column selection still referenced a long-removed column. A data migration removes the stale entry from every stored column selection, leaving the rest of the selection untouched.

  • tas-3737 Azure AD (Entra ID) login and profile photo πŸ› οΈ
    Note: Affects instances running 5.12.2 and newer. An Azure AD module configured with responseType: "id_token" signs users in again – the access token is optional, as it is used solely to fetch the profile photo – and responseType is now a documented enum of the two supported values. Profile-photo retrieval from Microsoft Graph works, and a photo that cannot be fetched, including on a Graph timeout, always leaves the user signed in. User.Read is added to the default scope of newly created Azure AD modules; existing modules keep working as they are and need the scope added by hand for their profile photos to start working.

  • tas-3764 Push notifications follow account status πŸ› οΈ
    Note: Both device lookups now require the owner to be an active user, so locking an account also stops mobile push delivery to its registered devices. Device rows and FCM tokens are left in place, so unlocking an account restores notifications without re-pairing the device.

  • tas-3759 DMS access log records case and task πŸ› οΈ
    Note: The Documents β†’ Accesses grid now shows the case for deletes, downloads, re-indexing and uploads rejected for a view-only substitute, on the success and the error path alike, and the task for a delete performed from a task's documents tab. Only newly written rows are affected.

  • tas-3776 The login-page news panel can be hidden again πŸ› οΈ
    Note: featureFlag.gui.showNews is honoured again, so white-labeled deployments can hide the panel.

  • tas-3876 Print scripts read long text variables in full πŸ› οΈ
    Note: A case overview script reading a text variable longer than 4000 bytes received the trimmed preview instead of the full value, so a variable holding larger JSON came back as invalid JSON and JSON.parse() threw. The print value of a text variable now prefers the full value, covering sanitized and unsanitized variable sets and archived cases alike.

  • tas-3542 Searching in documents works again πŸ› οΈ
    Note: The document search grid (Documents β†’ search) and the Documents tab of the global search work again. Thumbnail loading in document grids also no longer raises an alert when a thumbnail is missing or not yet generated – the grid falls back to the file-type icon, as intended.

  • tas-3856 / tas-3692 HR agenda - badge, list and hand-over use the same definition of "agenda" ⚠️ Breaking change:
    Note: A user's count badge, task list and ownership hand-over now select the same set of rows per category, so a fully handed-over agenda no longer shows a number in the bubble. Behaviour change: subprocess and event-wait rows no longer count as agenda items, and a task hand-over leaves them with their original solver instead of reassigning them. Case and variable counts are untouched.

  • tas-3241 HR agenda - full handover of a complete agenda ⚠️ Breaking change:
    Note: A full handover of a large agenda now runs as chunked bulk operations – owner change, rights rebuild and case-history writes – so it completes for users with many cases, tasks or variables, and large selections travel in the request body instead of the query string. Request-shape change for all change-user endpoints: they take a single selection object ({ mode: "ids" | "all" | "filter", … }), replacing the previous mix of body fields and query string. Query-string selection is no longer read.

  • tas-3856 / tas-3533 HR agenda - overviews, logs and single-row handover πŸ› οΈ
    Note: Handing over a single task or case from the agenda-handover modal works. The by-user overview is sorted by the display name it actually shows, and clicking a user opens the modal on the tab for the category being browsed. The by-variable grid's "Variable" column shows the localized variable name and can be sorted, filtered and exported. The logs grid loads with all its columns and can be filtered and sorted, including the "Changed by" column, and its Detail column reads in the reader's own language. The variables agenda-tab icon was unified.

  • tas-3856 Data grid - filters always join with a real operator πŸ› οΈ
    Note: A filter model without a stored logical operator – a custom filter saved by an older build, or the filter modal opened on one – now falls back to and, which also repairs existing saved filters the moment they are applied.

  • tas-3751 Tasks - "Mine + To pull" row menu πŸ› οΈ
    Note: All three actions in the three-dot row menu behave as expected: "Take over" opens the take-over confirmation, "Solve" performs the action, and "Detail" is disabled for non-takeable to-pull rows exactly like on the "To pull" tab.

  • tas-3629 Smart events - variable types in output selects πŸ› οΈ
    Note: The smart-event output selects ("Save state/value to variable") and the insert-variable popover show each variable's real type (document list, multiline text, sequence, checkbox, …) instead of "Text".

  • tas-3826 Grids with statically passed rows πŸ› οΈ
    Note: Template alias candidates, System health database activity and the diagram drill-through modal show the real record count in their footer. The take-alias-from-variable modal also closes only after the save succeeds.

  • tas-3729 Variable assignment editor πŸ› οΈ
    Note: Section height is computed from what the section actually renders, so sections with tall variables (document preview, multiselect, editor) no longer overflow or carry extra empty space, and the height is correct right after opening the editor. The assignment editor of a newly created task also offers the template's sections again.

  • tas-3890 ISDOC plugin - hex-string attachment names in PDFs πŸ› οΈ
    Note: isDoc.isIsdocPdfFile and isDoc.extract now detect a valid embedded invoice in PDFs whose producer writes the attachment's file name as a hexadecimal string broken over several lines (as PDFsharp does). The attachment walker strips PDF white-space from a hex-string name before decoding it.

πŸ”„ Changed

  • tas-3856 HR agenda - user modal leads with the three agenda categories
    Note: The user modal leads with Cases | Tasks | Variables and moves Task owner and Case owner into a three-dots menu behind them, the same pattern the cases and documents overviews use. Opened without a category, the modal opens on Cases.

  • tas-3856 HR agenda - "By agenda" renamed to "By variable"
    Note: Renamed in all eleven locales, with a hover tooltip explaining what the tab lists ("View by business variables"), since it shows business variables and their holders. The by-user overview's first sub-tab is now "Locked users" with the padlock icon instead of "Inactive users"; existing links keep working.

πŸ”§ Chore

  • tas-3800 npm run mig, npm run mig:init and npm run oracle:5.7:migration run with --max-old-space-size=8192
    Note: Gives an upgrade migration enough heap on large databases. The flag is a ceiling and nothing is reserved up front, but on a container whose memory limit is below 8 GB the process can be OOM-killed by the runtime instead, so the migration container should be sized accordingly.

πŸ“¦ [5.19.2] - 2026-08-05

✨ Added

  • tas-3663 ISDOC plugin - one entry point for every ISDOC input shape ✨
    Note: isDoc.extract(files) reads the ISDOC invoices out of a case document, whether that document is a plain .isdoc file, an .isdocx container or a PDF with an embedded .isdoc/.isdocx attachment, so a calculation no longer has to know which shape a supplier sent or plumb the DMS lookup itself. files accepts a document name, a DMSF_ID, an attachment variable, or an array mixing those; the result is { invoices, stored }. With the second argument storeAttachments, the files an .isdocx wrapped (typically the PDF visual) are stored as case documents. Encrypted DMS documents are decrypted on read. The same logic is available to template designers as the new IsDocSmartEvent. A document that cannot be processed fails the call with an error naming the document, so the case can be routed for manual processing instead of yielding nothing. The plugin gained a maxContainerSizeMb setting (default 64) capping the uncompressed size accepted when unpacking a container. Requires the plugin to be rebuilt/reinstalled (manifest 2.0.1).

πŸ› οΈ Fixed

  • tas-2324 Template import - sub-process templates imported as "Use compatible template" ⚠️ Breaking change:
    Note: Importing a template that runs an already-present template as a sub-process now works in "Use compatible template" mode. Compatible mode resolves variables, tasks and sections by name in the target template the consultant selects, instead of carrying ids from the source system; where no entity of that name exists, the import fails with the name of the missing variable, task or section. Compatible mode now also only reads the selected template and never writes to it, so it no longer duplicates the template's Case Overview sections on every import. The fix applies to new imports only: a template imported in compatible mode before the upgrade has to be imported again.

  • tas-3663 ISDOC plugin - PDF attachment detection πŸ› οΈ
    Note: isDoc.isIsdocPdfFile now recognizes a valid embedded ISDOC in every standard PDF attachment location – a flat name array, a direct Filespec reference, a name tree split over several nodes, and page-level attachment annotations – and takes the attachment name from the Filespec itself, since some producers store a placeholder such as Unnamed in the name tree. isDoc.parseIsdocPdfFileContent now uses a structural ISDOC check; the parsed invoice output shape is unchanged.

πŸ”„ Changed

  • tas-3663 DMS file inputs are normalized the same way across every calculation API
    Note: The rule that turns a calculation file input into DMS file identifiers moved to a shared normalizer, so every calculation API accepts DMS documents in the same shapes.

  • tas-3724 Workflow engine per-cycle tracing moved from info to debug ⚠️ Breaking change:
    Note: Lines reporting that a check was about to happen or that nothing had changed yet were emitted for every task, link and process on every workflow pass and every cron tick. These are now debug (their verbose detail companions trace), together with the per-item lines of PostponedTaskCron and the per-kind plugin import lines. No log line was removed, and outcome-level logging – activating/finishing a task, activating a process or event, routing decisions, solver selection, and every warning and error – deliberately stays at info. Instances that relied on reading the demoted lines at the default level need logging.level raised to debug.


πŸ“¦ [5.19.1] - 2026-08-04

✨ Added

  • tas-3215 Template variable alias management ✨
    Note: Template variable aliases – the fixed per-template pool of overview columns – can now be managed by an administrator directly from the template variables grid: assign a free alias to a variable that has none, remove a variable's alias, or take the alias of another variable of the same kind. A new "Alias candidates" analysis (behind an are-you-sure confirm, because the query is heavy) lists, per alias kind (text / number / date), the variables holding an alias ordered by how "dead" they are – never-used first, based on how many cases hold a value and how many historical value changes exist – plus how many overviews reference each variable. Removing or taking an alias is rejected while the variable is referenced by a custom view column or filter. Assigning or moving an alias only clears the alias column for the receiving variable's cases; values fill in again as instance variables are next written, so overviews on the receiving variable show empty values until then.

πŸ› οΈ Fixed

  • tas-3625 Plugin store - installing an update replaces the previous version πŸ› οΈ
    Note: Install and uninstall match a plugin by its manifest sysname and remove every on-disk folder for it, so an update no longer writes a second, parallel folder. The store no longer offers an update for an already-updated plugin, and delete removes the selected version. The "restart required" state is derived on the backend from disk, so it survives page reloads: the Restart button appears only when a restart is genuinely pending, and a freshly installed plugin keeps its state after a reload. The installed-plugins grid also lists a plugin that is on disk but not yet loaded with a "restart required" status.

  • tas-3722 Case builder - "Automatic height" on overview and dynamic-table sections πŸ› οΈ
    Note: The setting sizes the section to the table's actual content (header + loaded rows + footer), capped at 70 % of the viewport height, instead of always rendering the table area 70vh tall. Applies both in the Case Overview builder and in the case detail.


πŸ“¦ [5.19.0] - 2026-08-03

✨ Added

  • tas-2398 MCP server - expose TAS AI tools to external MCP clients ✨
    Note: TAS AI tools are exposed to external MCP clients (Claude Desktop, Claude Code, …) over a stateless MCP Streamable HTTP endpoint POST /mcp/:scenario?, authenticated with an API token. The optional scenario path segment (case-creation, case-editing, case-lookup, knowledge, account, administration) scopes which tool collections are exposed; bare /mcp exposes all. Every tool call is audited. Requires the migration adding USER_ID, COLLECTION and SOURCE to AI_LLM_TOOL_CALL. Limitation: write tools that require a confirmation step in chat execute immediately over MCP, as the protocol cannot enforce a server-side human-in-the-loop round-trip.

  • tas-3627 AI template builder - template task links ✨
    Note: The AI template builder can propose and import template task links (the workflow-graph edges) alongside variables and tasks in the same conversation. Links carry the source task's split-mode branching (parallel/exclusive/inclusive), a recursive condition tree, priority, default (else) branch, and the required diagram ports. The orchestrator plans links after tasks, since a link's from/to tasks and any condition variables must already exist or be planned first.

  • tas-3429 Case diagram - per-node drill-through ✨ ⚠️ Breaking change:
    Note: Diagram nodes carry every collapsed instance task and finished execution; a clickable count badge opens a modal listing each copy/run with its solver, status, dates and note. The side panel labels whether case or task detail is shown, clicking a selected task again deselects it, statuses get distinct colors including a state for waiting tasks with no solver, and the modal shows a note that the diagram is an orientation aid plus drift and archived warnings. The INSTANCE_GRAPH and ARCH_INSTANCE_GRAPH tables are dropped – the case diagram is composed live from the current template layout and the case's instance tasks and history, so every case diagram, archived ones included, always reflects the current template. The GET /processes/:id/graph payload changed (one node per template task with instances / history_entries detail arrays and drift origin markers) and the endpoint now enforces process rights – an inaccessible case returns 400 LACK_OF_PERMISSIONS instead of an empty diagram.

  • tas-3558 Prints and case overviews - script mapping ✨
    Note: Prints / case overviews and template-task dynamic conditions can map a subset of frontend scripts to load instead of always loading every active CO script – faster loading, and a broken script no longer affects prints and tasks that don't map it. The mapping is edited via a "Loaded scripts" multi-select in the print/CO editor and a header button with a count pill in the dynamic-conditions modal. Server-side print rendering filters the same way. Deleting a script strips it from all mappings, and template export/import carries and remaps them. Backward compatible: no mapping loads all active scripts as before. Requires the tas-3558 migration.

  • tas-3552 Variable assignment - import from another template task ✨
    Note: The variable assignment, and optionally its dynamic conditions, can be imported from another template task. A confirmation warns before overwriting a non-empty assignment or non-empty conditions, and deleting the assignment can also delete the imported conditions via a checkbox.

  • tas-3561 DocxGeneratorSmartEvent - "Save as PDF" ✨ ⚠️ Breaking change:
    Note: A new "Save as PDF" checkbox additionally stores a PDF copy of the generated document in the DMS (converted via LibreOffice, named after the output filename); the .docx is always stored. Also available from calculations via docxGenerator.generate({ saveAsPdf: true, … }). The output contract changed – the smart event's result variable and docxGenerator.generate() return the stored files as a { name, id } list instead of a single DMSF_ID, e.g. [{"name":"out.docx","id":12},{"name":"out.pdf","id":13}]. Existing calculations reading the previous plain id must switch to result[0].id.

  • tas-1951 New calculation functions storage.moveDmsFilesToCase / storage.moveDmsFilesFromCase ✨
    Note: Move DMS documents between cases, selecting by file id, file name, attachment variable, or all case documents. The move carries the whole revision chain, recomputes main/sub-process visibility from the target case, detaches the task binding, rewrites the case/template DMS tags, refreshes the fulltext index, and logs a MOVE_FILE entry into the DMS access log and a record into the case history of both cases.

  • tas-3646 New calculation functions lib.getUsers / lib.getRoles / lib.getOrgUnits ✨
    Note: Structured querying of system dimensions using the same { filters, sort, page } query shape as the AI query tools (operators eq, ne, in, nin, contains, startsWith, endsWith, gt, gte, lt, lte, isNull, isNotNull, cursor paging, optional total count). This enables partial-match lookups – e.g. finding a user by part of the name – directly in the calculation. Each function mirrors its REST list endpoint including its visibility restrictions; USER_PASSWORD is never returned. Available in task JS, process JS, console and authority sandboxes.

  • tas-3654 MS Graph mail crons - configuration overhaul ✨
    Note: The MS Graph mail crons render each mailbox as a collapsible card titled by its email address, with a "duplicate mailbox" button, so configurations with many mailboxes stay compact. The mailbox clientSecret can reference a stored vault secret ({{vault:name}}) instead of being kept in plain text. The per-mailbox user, template process and group header fields render as searchable dropdowns populated from the environment instead of raw numeric inputs. A "Discover folders" button browses a mailbox's folder tree live from Microsoft Graph and writes the chosen folder id straight into the input/output folder setting. The seeded default mailbox ships a usable field mapping. Newly created "Create Processes from MS Graph mails" crons default useEmailObjectInDataHolder to false so the field mapping populates holderData; existing crons keep their saved parameters.

  • tas-3654 Crons - default cron set on a fresh environment ✨
    Note: A fresh environment ships with a default set of cron jobs pre-configured via a seed migration instead of an empty table. Each seeded cron mirrors its class defaults and is inserted inactive, since each needs an external integration or explicit config first. The seed only inserts when the crons table is empty, so existing environments are untouched. The "Add cron" dialog pre-selects active for exactly that default set and inactive for every other cron.

  • tas-3654 Crons - logs button and clearer "Add cron" dialog ✨
    Note: The cron detail header gained a "Logs" button that opens the run-logs viewer scoped to the current cron. In the "Add cron" dialog the technical-name field is relabelled "Select cron" and the remaining fields appear only once a cron class is picked.

  • tas-3608 Cron administration - technical name column and quick activate ✨
    Note: The crons overview shows and filters by the technical cron name (the cron class the scheduler runs) for backwards-compatible lookup, each row's three-dots menu gains an Activate/Deactivate action, and the Monitor tab gains an info button opening a help dialog that explains every health indicator and how it is computed (EN/CS).

  • tas-3618 / tas-3609 System health page tuning ✨
    Note: The Overview status-count chips are clickable to filter components by status, each tab carries a short info line describing it, and the Database Activity tab shows the database server version. The Elasticsearch check reports node disk usage and warns/crits at ES's own watermarks (85 % / 90 %); the Host resources check reports the backend's own disk usage at the same thresholds. The Cron monitor tab lists only active crons by default with a "Show inactive" toggle and lets each admin star crons as favourites that pin to the top. "Running queries" is renamed to "Database sessions" to distinguish DB-server sessions from the application's own queries. A new admin-only "System health" dashboard widget shows either an aggregate-status summary or a per-component status list, can show uptime per backend, can open the Health page in a new window, and can render selected components with live graphs directly on the dashboard.

  • tas-3607 Plugin store tuning ✨
    Note: Administrators can remove an installed plugin, a full-screen spinner overlay indicates install/update progress, and the "Restart backends" action darkens the screen and polls until the fleet is serving again before reporting success. Uninstall deletes the plugin folder and requires a restart – running instances keep the plugin loaded until then.

  • tas-3589 Slim script list endpoint ✨
    Note: The scripts admin grid, template copy/import and the template-task script dropdown use a slim list endpoint (id, name, type, active, last-changed only) instead of downloading every script's body, and the template-task editor fetches bodies lazily only for scripts assigned to a calculation box.

  • tas-3569 Smart events form improvements ✨
    Note: A "create variable" shortcut in the event outputs card, tooltips describing the format stored into the status/value variables, and variable type labels in the output variable selects.

  • tas-3490 AI chat - milestones menu for longer conversations ✨
    Note: Once a conversation has five user messages, a rail on the right of the thread shows one line per user message; hovering or clicking it opens a scrollable list and selecting a message scrolls the conversation to it.

  • tas-3405 AI chat - attachment UI (disabled) ✨
    Note: Frontend preparation only – a plus button in the composer offers a file picker in the browser and a Camera/Photos/Files menu in the native mobile app, with selected files shown as removable chips. The UI ships disabled until the backend upload endpoint is released.

  • AI chat - thinking steps are collapsible behind a "Thinking" toggle ✨
    Note: Expanded while streaming, collapsed once the response finishes. The unread-response badge also no longer lingers when a reply arrives while the conversation is open and visible but the window unfocused.

  • tas-3046 Case builder - data source shown on sections ✨
    Note: Overview, dynamic-table and dynamic-rows sections in the Case Overview builder show which data source they read from ("Data source: Overview - ") in the section toolbar, so the source is visible without opening the section's configuration.

  • tas-3676 Query tools match every active language mutation ✨
    Note: A filter on a language-extensible field (e.g. a task name) transparently matches every active language mutation, so the AI builder's query_template_tasks finds tasks by the localized name the user actually sees.

  • tas-3336 License handling ✨ ⚠️ Breaking change:
    Note: Storing a license returns the issued license UUID so it can be propagated to ServiceHub, and the display name is derived solely from the license – the name claim embedded in the license JWT when present, otherwise a placeholder generated from the license's validity dates. Request-shape change: the POST /license name field has been removed (previously required). The "Add license" admin modal no longer has a name field and shows the returned UUID with a copy button after saving.

πŸ› οΈ Fixed

  • tas-3710 Icon rendering in frontend images built from 2026-07-28 onwards πŸ› οΈ
    Note: Frontend images built between 2026-07-28 and this release could render wrong pictograms or literal letters, because a build-time asset issue prevented the icon fonts from registering in the browser. The build now produces correct icon fonts regardless of the resolved dependency version. An image built in that window has to be rebuilt or re-pulled from this release to pick up the fix.

  • tas-3673 Upgrading from 5.17.x aborted npm run mig πŸ› οΈ
    Note: The upgrade could abort with MSSQL error 2705 (Column names in each table must be unique) on the secret_store.valid_from column. The column add is now idempotent on both engines.

  • tas-3712 "Run scheduled tasks and events (PARALLEL)" cron on PostgreSQL πŸ› οΈ
    Note: The cron runs on PostgreSQL – the background-events query compares the process id as text on both engines, instead of relying on implicit coercion. Each half of the cron also has its own error handling, so a failure in the events half is logged and the scheduled-tasks half still runs. The same query serves the systemApi background-events lookup.

  • tas-3668 "Send task reports and deadlines" cron πŸ› οΈ
    Note: The cron's deadline filter now produces valid SQL on both engines and the cron completes. Minor behaviour change: a task counts as overdue when its deadline is before the current moment rather than before the start of today, matching the existing workflow overdue indicator on the same column.

  • tas-3703 Deadline escalation e-mails to managers and supervisors πŸ› οΈ
    Note: The escalation templates read the data shape the query returns, so escalation mails are sent again. Daily report mails were not affected.

  • tas-3665 AD synchronization cron πŸ› οΈ
    Note: The cron resolves its configured LDAP authentication method correctly on both database engines and synchronizes users again. Instances using AD sync should check that the next scheduled run completes with the expected number of synchronized users.

  • tas-3641 Cron parameters that do not comply with their schema ⚠️ Breaking change:
    Note: Cron parameters stored before the parameter schemas were introduced are normalized against the owning cron class's schema on every migrate up: scalar type mismatches are coerced, forbidden properties are stripped, defaults are never injected, and a row that still does not validate is left untouched and logged – review migration logs after upgrading. Creating or updating a cron through the API now validates parameters server-side and rejects violations with INVALID_CRON_PARAMETERS. The audit also corrected the schemas themselves (XML process import, MS Graph, iDoklad, the database index-rebuild and health-report crons), and the scheduler resolves a cron stored under its exact class name.

  • tas-3654 Cron administration - "Factory settings" and run-log severity πŸ› οΈ
    Note: A factory reset now unconditionally restores the timing, description, parameters and active status from the cron class defaults, instead of only filling values that were still empty; the user-defined name is preserved. Cron run-log entries also show the correct severity, as the grid now uses the same level scale as the backend.

  • tas-3654 MS Graph - connections with an empty scope πŸ› οΈ
    Note: An empty or missing auth.scope, the intended default, falls back to https://graph.microsoft.com/.default. The mailbox mapping field is also a free-form key/value map now, so arbitrary target variables can be mapped.

  • tas-3615 Cron administration - names and descriptions πŸ› οΈ
    Note: Dropped the misleading word "arango" from the DeleteLogs cron's default name and description, and clarified several class-default descriptions that merely repeated the name (AD sync, secret store & API token validation, password expiration, instantiate process, sync process rights, template process shredding).

  • tas-3640 Organizational structure import πŸ› οΈ
    Note: The import detects already-existing units, so a re-import no longer creates duplicates and "overwrite existing" rewrites every matched unit. The preview uses the exact same matching semantics as the import itself and reports duplicate file rows; the hierarchy preview tree was removed. Separately, the org-structure tree anchors on the real root unit when orphaned root-level rows exist.

  • tas-3564 Saving an organizational unit with many members πŸ› οΈ
    Note: Saving a unit with 2000+ users on MS SQL Server no longer fails with The incoming request has too many parameters. Only the membership delta is written, so a no-op save (uploading a logo, re-saving) performs zero membership writes.

  • tas-3647 Dynamic tables - saving a cell value longer than 4000 characters πŸ› οΈ
    Note: Values longer than 4000 characters save on MSSQL; values arriving from the components5.0 row editor are offloaded to CLOB storage correctly and are sized in characters.

  • tas-3648 Multi-instance task iterating over a dynamic-row column πŸ› οΈ
    Note: The iterated column's kind is derived from the column definition, so lib.iterator(1) resolves a user / org. unit / role for entity-picker columns and returns the raw value for plain text or number columns. A DR of users still assigns tasks per user as before.

  • tas-3699 lib.dynListToString() on dynamic-list variables πŸ› οΈ
    Note: Affects instances running 5.12.31 and newer. Values are filled through the variable entity itself, handling both multi-choice and single-choice dynamic lists, and a missing value yields an empty string instead of throwing.

  • tas-3697 setValue(object) on a JSON / dynamic-row variable πŸ› οΈ
    Note: Writing an object into a dynamic-row variable no longer records a parse error in the audit log; the value was stored correctly throughout. This also stops stored date cells being rewritten to a different format on re-store.

  • tas-3567 Saving a script in dynamic conditions or a print template πŸ› οΈ
    Note: Saving works again after the Babel 8 upgrade – all call sites pass the imported presets directly instead of resolving preset names at transform time.

  • tas-3623 varDefOn() on a dynamic-rows variable πŸ› οΈ
    Note: Missing column definitions are skipped silently again, so a script whose tableDefinition.columns covers only some of the table's columns no longer fails.

  • tas-3717 Saving a new print template on PostgreSQL πŸ› οΈ
    Note: The print order is part of the request validation, so an empty value becomes null and falls back to the column default, keeping print ordering identical on both database engines.

  • tas-3720 Saving a plan on PostgreSQL πŸ› οΈ
    Note: The assessment org unit and role are validated, so an empty value becomes null and a non-numeric value is refused with a clear 400. On MSSQL an empty value could previously be stored as an invalid org unit / role reference, so existing plans are worth reviewing.

  • tas-3632 Importing a template exported from an older version πŸ› οΈ
    Note: The importer drops a removed legacy column before inserting into the JS calculations table, so the import completes.

  • tas-3636 Case history entries show the real time ⚠️ Breaking change:
    Note: Process-level history entries (DMS document moves, case owner changes, HR agenda changes) recorded a date without a time, so they displayed roughly midnight. The column is now a full timestamp (live and archive table) and new entries record the real time. Requires the tas-3636 migration; existing rows keep midnight, as their time of day was never stored.

  • tas-3614 "Case visible for role" on a template header πŸ› οΈ
    Note: The value is persisted again and survives a page refresh.

  • tas-3569 Smart events - saved event parameters after reopening the task πŸ› οΈ
    Note: Saved smart-event parameters are preserved when the task is reopened and no longer block re-saving with "required fields not filled". The task endpoint returns the event parameters as the raw stored JSON string, so API consumers reading this field must JSON.parse it. Template documents can also be picked from shared documents as well as AI sources.

  • tas-3626 / tas-3619 Diagram - saving the graph after touching a task or a link πŸ› οΈ
    Note: The graph saves correctly after a task has been selected or a link edited; a link-touched task with no real change is skipped rather than re-saved with stale graph data.

  • tas-3562 Data grid - clicking the sort of a default-sorted column πŸ› οΈ
    Note: Sort removal flips the default column's direction, and on any other column the third click restores the table's default sort.

  • tas-3701 Overviews - searching in the folder tree keeps the saved expansion πŸ› οΈ
    Note: The search-driven "expand all folders" state is transient; leaving the page or clearing the search restores exactly the folders the user had expanded by hand.

  • tas-3687 Copying roles from another user πŸ› οΈ
    Note: The endpoint's service is injected correctly, so copying roles works. The same fix applies to the "Password Expiration Notification Mails" cron.

  • tas-3656 An Elasticsearch authentication failure no longer logs the user out πŸ› οΈ
    Note: Opening the Documents or the Logs page while the Elasticsearch client rejects authentication no longer redirects to the login page. The response status is taken only from TAS exceptions and Fastify's own errors; every other failure is reported as 500 with the sanitized message. Genuine authentication and session failures are unaffected.

  • tas-3578 Usage statistics update through the day πŸ› οΈ
    Note: Monthly usage statistics (USERS_THAT_SOLVED_A_TASK, COMPLETED_USERS_TASKS, CREATED_PROCESSES, …) update on every cron run instead of keeping the value of the first run of the day. The update targets the month's row by its primary key.

  • tas-3609 System health - Database Activity card πŸ› οΈ
    Note: When live-activity reads are refused (e.g. a SQL Server user without VIEW SERVER STATE), the card degrades to an "unknown" status with a short message instead of showing the failing statement. Health warnings also render in a real orange instead of the theme's mustard.

  • tas-3651 MCP / AI tool names over the 64-character limit ⚠️ Breaking change:
    Note: Tool names could exceed the LLM provider's 64-character function-name limit and be rejected with a 400. The MCP server now exposes raw, unprefixed tool names – the collection is conveyed in the tool description as [CollectionName] … – and the LLM client deterministically shortens any over-limit name on the wire, restoring the original on the response so callers and the audit are unaffected.

  • tas-3511 AI case tools - dynamic-row variables πŸ› οΈ
    Note: Dynamic rows are published to the model as a structured column-major schema built from the DR's column definitions, so the AI assistant can fill dynamic-row variables when creating or editing a case and a free-text value fails validation up front rather than at store time. Dynamic-table variable schemas describe the value as an existing row index, null is accepted the way the schema advertises, and a legitimate 0 in a number list is accepted.

  • tas-3689 AI chat - the assistant asked for permission twice πŸ› οΈ
    Note: The system prompt describes the deterministic approval gate and forbids prose permission-asking, so the user confirms a confirmation-gated write tool only once, on the approve/reject card.

  • tas-3676 AI builder - duplicates on failed identification πŸ› οΈ
    Note: The template builder no longer creates duplicates when it fails to identify an existing element: an empty filtered lookup is not taken as proof of absence, creating a new element as a fallback for a failed identification on an edit is forbidden, and the quality gate turns that case into a clarification question naming candidate elements.

  • tas-3676 Template tasks - assignment, offsets and type-foreign fields are validated at write ⚠️ Breaking change:
    Note: Task assignment is normalized to the GUI contract in the shared write path – automatic and notification tasks get their assignment fields cleared, every solver-capable type defaults exactly as the task editor saves it (builder- and API-created tasks no longer show an empty "Reference person"), and mutually exclusive fields are enforced. Deadline and duration offsets are validated: ps/ts values must be days[:hours[:minutes]] and vo/vc the id of a date variable. Type-foreign payload sections are rejected instead of being dropped (an email notification attached to an automatic task used to survive the builder review and then be ignored by the import). Task writes that previously stored or ignored such fields now fail validation – this affects REST API callers sending such payloads; the GUI already conforms.

  • tas-3046 Case overview - uploading a document and variable rendering πŸ› οΈ
    Note: A file's details (upload date, uploading user, source-variable tag) show immediately after upload instead of only after a page refresh, and a section with "Automatic section height" enabled is capped at 80 % of the viewport height and scrolls. Dynamic-table and dynamic-list values render without surrounding quotes, the "is empty" / "is not empty" operators in tab and cell hide conditions recognize empty multichoice values, and long texts wrap inside variable cells instead of overflowing.

  • tas-3606 Production images report the exact release version ⚠️ Breaking change:
    Note: The backend version is sourced from the mandatory TAS_APP_VERSION env value, sealed into every image from the git tag at build time, so application.version matches the image tag exactly, including pre-release suffixes such as 5.19.0-rc0. TAS_APP_VERSION is now mandatory – the backend does not boot if it is unset. The value is used for plugin min/max compatibility checks, so plugin version ceilings must be current.

  • tas-3607 Plugin install / update from the store πŸ› οΈ
    Note: Install now sniffs the archive format and strips the archive's top-level directory, so the .tar.gz archives served by the store install correctly. After a successful install the store card shows a disabled "Restart required" state until the backends are restarted, and the "Available version" grid column no longer wraps on smaller screens.

  • tas-3608 MS Graph cron - numeric ids accepted πŸ› οΈ

  • tas-3679 Graph - link panel conditions show the variable name alongside its id (template and case graph) πŸ› οΈ

  • tas-3617 Colour corrections across the TAS interface πŸ› οΈ

  • tas-3693 Adding a license no longer opens a redundant "License saved" modal; the success alert is the only confirmation πŸ› οΈ

  • tas-3584 News post creation no longer prepends https// πŸ› οΈ

πŸ”§ Chore

  • tas-3672 Two new CLI commands for debugging migration problems: npm run db:migrations dumps the migrations table as JSON, and npm run db:migrations:set-state -- name=<migrationName> state=<executed|pending> changes the recorded state of a single migration without running or reverting its SQL
    Note: Neither direction touches the schema – state=executed requires the schema to already be in the state the migration would have produced, and state=pending makes the migration's SQL run again against a schema that may already contain its changes.

Frantisek Brych Updated by Frantisek Brych

v4.15 (Obsolete version)

Contact

Syca (opens in a new tab)

Powered by HelpDocs (opens in a new tab)