Java 25 is the new LTS release (succeeding Java 21). The entire build and runtime toolchain has been updated across all server components.
Java 25 is the new LTS release (succeeding Java 21). The entire build and runtime toolchain has been updated across all server components.
A new PSA_GEO_SERVICE_QUOTA environment variable enables optional rate-limiting of all outgoing geo API calls. The variable accepts three parameters:
LIMIT — maximum number of calls allowed per period (default 0 = no limit)SEQUENCE — name of the database sequence used as the counter (default GEO_SVC)MODE— behavior when the limit is reached:ERROR (default) — blocks the call and throws an error shown to the userWARN — allows the call but writes a warning to the session and the server logDEBUG — silently allows the callThe quota check (PsaGeoQue.checkServiceQuota()) is called before every outbound geo API request: address look-ups, address field autocompletion and route calculation.
The reset mechanism is implemented at the platform level: A new column in the sequence table allows any DB sequence to reset automatically if the period changes (e.g. new month). On every "next sequence" call the current period string is compared to the stored value. If they differ, the counter is reset to its minimum before incrementing. This works across all supported databases (Oracle, PostgreSQL, SQL Server).
Before issuing a geo API request for an address, the system now checks whether an identical address (matching street, zip, city, and country) with already-stored coordinates exists in PSA_ADR. If one is found, the stored latitude and longitude is reused. The external API call is only made when no usable coordinates are found.
The visit report wizard that opens when closing an appointment now includes a sixth selection step for the appointment's assigned projects. The selected projects are shown as a dialog tag (comma-separated list). Clicking the field opens the standard multi-select project dialog, which includes the option to mark a main project.
A new LBL field (up to 2000 characters) has been added to the PSA_PRO_CON data object. Multiple labels are stored in a single field, separated by semicolons.
Users can type labels directly into the field or open a modal selector that lists every label already used in the current project. The field is single-language and requires no central administration.
When a customizer incorporates a fix for a reported defect — or changes the scope of a feature — the user who originally reported it has no clear signal that there is a new to-do on their side. The new "Retest" flag on the test definition closes that gap: The customizer flips it to on to indicate to the user to "please run this test again", and the flag is clearly visible on the test record.
An administrator (or any user with the required permissions on the test definition) can toggle the flag. When a test execution is recorded or a result is entered against the test, the flag is reset to off automatically, so it only ever stays set until the user acts on it.
Previously, a structure copy of a mailing list performed the copy via the open dialog and therefore only replicated the records that were currently loaded in the members tab. If the dialog was limited to 1000 visible rows, the copy of a 10 000-member list ended up with only those 1000 members.
The structure copy for both list types is now performed server-side, modeled after the existing specialized copy functions for projects, documents, service objects, templates, and questionnaires. The structure copy copies the base record and all relations to contacts.
After the server-side copy completes, a modal result dialog opens so the user can edit the copied record and confirm or abort the operation. Since the copy no longer walks through the dialog, it is significantly faster for lists with many contacts.
8.4 patch 10
The internal constant LATEST_DATE used by the macro processor previously resolved to 2035-01-01 00:00:00, which was a date that is meanwhile approaching. The value has been updated to 9999-01-01 00:00:00 UTC (internal representation 99990101000000).
The last possible second (9999-12-31 23:59:59) was deliberately not used to avoid timezone-conversion overflows when dates are shifted across timezone boundaries.
Previously, Automations, Planning Board, and GenAI each required their own URL environment variable (psa.neoletter.url, psa.planning_board.url, psa.gen.ai.instance.id). All JustRelate platform products share the same base URL pattern (https://api.justrelate.com/<product>/instances/<id>), so these separate entries were redundant.
After this change, the configuration dialog only writes four values:
psa.iam.instance — the shared instance IDpsa.iam.account — the shared IAM account IDpsa.iam.id / psa.iam.secret — the IAM client credentialsProduct clients (PsaClient.getUrl()) derive their full endpoint URL from psa.iam.instance automatically if no explicit URL property is found.
| New property / environment | replaces |
|---|---|
psa.iam.instance / PSA_IAM_INSTANCE | psa.neoletter.urlpsa.planning_board.urlpsa.gen.ai.instance.id |
psa.iam.account / PSA_IAM_ACCOUNT | psa.rst.api.iam.acc.id |
Migration
Existing installations that still have the old per-product environment variables configured will continue to work — the code falls back to the old keys.
8.4 Patch 10
The portal REST API full-text search routes queries through EUREKA and then applies a second-stage filter to restrict results to the calling customer. EUREKA caps results at 1000 hits, so if a query matches more than 1000 records across all customers, the customer-specific records could be beyond that cap — causing the caller to receive too few results or none at all.
The fix introduces a new index field POR_KEY_001 that stores the customer GID (CON_GID) for all indexed project types. For service objects, supplier and carrier GIDs are also stored. The portal search now passes the caller's customer key as an additional filter on POR_KEY_001 directly to EUREKA, so only records belonging to that customer are considered from the start and the 1000-results cap no longer causes any data to be missed.
Administrative action is required after upgrading because the new field is not present in existing index documents. Until a record is re-indexed, the field is absent and the search will not find it. After upgrading, run a partial re-index of the affected DTO types. Copy the EUREKA index job and set the parameters:
8.4 Patch 10
Previously, chatting with the AI (SalesBot/ChatBot) was done through the regular messaging UI by sending messages to a special bot user. A background job generated a reply and posted it back as a chat message. This worked but was awkward — it polluted the message log, offered no dedicated conversation UX, and tied the chat flow to the generic messaging infrastructure.
A new dedicated dialog replaces this workaround. The dialog is available in the sidebar navigation and provides a proper chat experience built directly on top of the GenAI service.
Features
PSA_AI_CHAT_CLR environment variable.Requirements
8.4 Patch 9
The SOAP integration in the core server used Apache Axis 1.2, which has long reached end of life. Upgrading to Axis 2 would require a full rewrite, and only a small number of customers still use SOAP — so the integration has been carved out of the shipped server rather than migrated. New SOAP-based integrations should use REST instead.
What changed
PscSoap_1.0.0.jar). The following dependency jars, previously in the core, are now dependencies of the optional module only: axis.jar, commons-discovery-0.5.jar, jaxrpc-pisa.jar, saaj-impl-1.5.1.jar.Installing SOAP again (customers that still need it)
The release folder contains soap.zip, which bundles PscSoap_1.0.0.jar plus its referenced third-party jars (Axis 1.2 et al., wired through the jar's manifest classpath). To re-enable SOAP:
soap.zip into the server's ext directory.PscSoap_1.0.0.jar to the classpath.The extracted module is not maintained. Use it at your own risk.
Previously, the LST_REA field on projects (e.g. quotes) stored only a single, unlocalized string even though the "Loss reason" master table (PSA_LST_REA) already maintained translated names per language. In multi-language environments, this meant that users working in different languages always saw the raw value rather than their own translation.
The field is now stored and resolved per configured user language.
During the upgrade, a function in the SQL administration will automatically migrate the field to multi-language.
When looking up a contact by email address, the search now runs in two phases. First, the query ignores contacts flagged as duplicates and considers only master records. Only if that first phase returns no results, the search falls back to duplicate contacts.
Previously, if an email address was not unique, but all but one of the matching contacts were marked as duplicates, the lookup could return a duplicate instead of the master. As a result, e.g., incoming emails were assigned to the duplicate contact rather than to the surviving master.
The Classic CRM exposes a /mcp REST endpoint that implements the Model Context Protocol, enabling AI coding assistants and agents (e.g. Claude Code) to query and manipulate CRM data through natural language.
Architecture
/mcp endpoint sits outside the standard /salesportal path and dispatches tools/list and tools/call JSON-RPC requests.X-IAM-Client-ID / X-IAM-Secret): The server fetches and validates an IAM token server-side, so no session is required on the client side.de.pisa.psa.com.genai.mcp.json.MCPTool.de.pisa.psa.com.genai.mcp.adapter.RestApiToolAdapter) — maps an existing Sales Portal REST endpoint to an MCP tool automatically. The parameter ENDPOINT:=GET salesportal/order is all that is needed. The adapter derives the JSON Schema from the endpoint's data object and event handler, and translates enum codes to/from their human-readable titles.de.pisa.psa.salesbot.mcp.ToolAdapter) — wraps an existing SalesBotToolFactory tool as an MCP tool.Built-in tools (shipped as default data model)
Setting it up for 8.4
Import the two loader packages PSA_MCP_BAS_EXP.zip and PSA_MCP_DAT_EXP.zip (available on S3 at s3://pisa-releases/08.04-20251126) via the repository upgrade wizard in the developer toolbox.
Connecting Claude Code
Generate an API key (client ID + secret) in the JustRelate Console for your instance, then run:
After restarting Claude Code, run /mcp to see the registered tools. A quick smoke test: "Who am I in the CRM?"
8.4 Patch 8
Cockpit chart tiles (gauge, bar, stacked-bar, line+bar, pie, funnel) and a few related standalone chart forms previously always rendered a server-side PNG image, regardless of the client. A client that advertises it can render charts itself (the JSC "JSON charts" capability flag) now receives the chart as structured JSON data instead — the same data model already used by the REST/NeoDXP cockpit API — and renders it client-side rather than displaying a static image.
What moved to JSON (when the client requests it)
PsaCcpDiaSciApp base class (gauge, bar, stacked-bar, line+bar, pie, and the sales-funnel cockpit tile).PsaProSalFnlApp, PsaProConStaFnlApp, PsaProConStaDiaApp), which are embedded in project/sales dialogs outside the cockpit itself.What intentionally still renders PNG
Chart-data fidelity fixes bundled with the format change
The JSON payload now carries the same magnitude/currency suffix (e.g. "T€" for thousands), value-scale, and legend information (position, and small-tile vs. maximized visibility) that the PNG renderer already showed, so a chart looks the same regardless of which representation the client uses.
Customizing
de.pisa.psa.ifc.dia.PsaDiaUti centralizes the relevant helpers (isUseJSONData(PscFrm), getChartViewType(PscFrm)) for any dialog that renders a chart, so custom dialogs can opt in the same way.Previously, a SocketTimeoutException on any outgoing HTTP call to an external JustRelate service caused the operation to fail immediately. The fix adds an ExponentialBackoffStrategy configured to retry on TimeoutException to the REST clients used in three places:
/userinfo request used for token validationPsaRstApiEvtHdlOut) — REST calls initiated from event handler implementations8.4 Patch 8
8.3 Patch 21
8.2 Patch 35
The REST client retry strategy previously only retried on HTTP 429 (too many requests). AWS Bedrock (and other services) also return HTTP 503 under high load, which was not retried and caused immediate failures.
The default retry trigger set now includes 429 and the full 5xx range (500–599). All consumers of the retry strategy — IAM, Automations, GenAI, and the Planning Board — automatically inherit this behaviour without any configuration change.
8.4 Patch 7
8.3 Patch 20
8.2 Patch 34
When synchronising a mailing list, recipient records are transferred to Automations in a single delivery block. If any field value exceeded the limit accepted by the Automations API (e.g. a salutation longer than 50 characters), Automations returned an error for the entire block after processing it, which could take some time.
Recipient data is now validated against the Automations API field length limits before the delivery block is sent. An invalid recipient is rejected immediately with a human-readable warning that identifies the affected record by name and email address.
Field limits applied (matching the Automations API spec)
| Field | Max length |
|---|---|
email | 120 |
salutation, gender, phone_number | 50 |
given_name, family_name, middle_name, name, company | 250 |
url | 1000 |
8.4 Patch 8
Dropdown fields in drill-downs (e.g. the "Occasion" selector) were limited to 100 entries. The root cause was that fetching the distinct values for the dropdown, the filter query set on the visible field was not being copied to the cloned data object used for the distinct fetch. As a result, the distinct query ran unfiltered and hit the default 100-record limit immediately, regardless of what the user had typed.
The fix copies the visible-field query from the source data object to the cloned data object before executing the distinct fetch, so the filter is applied correctly and the full matching result set is returned.
8.4 Patch 7
The "Change name of organization" function failed with an "invalid field" error if the company was assigned as a planner to an object. During a rename, the function iterates over all related objects to update the contact reference field. For planner objects, the data object type loaded during the rename did not directly carry the contact-relation field — so setting the data threw an error.
The fix checks if the field is present before attempting to set the field directly. If the field is absent, it resolves the correct data object class for the object, loads the record under that class, and then applies the update.
8.4 Patch 7
Clicking a colleague's avatar to address them in a pinboard message caused the @username handle to be appended as plain text regardless of whether the message field contained HTML content. In an HTML message, this caused the handle — and surrounding markup — to appear as raw HTML in the posted text.
The fix detects whether the current message text is HTML markup. If it is, the handle is injected inside the <body> in a new <div> element rather than being concatenated as a plain string. For plain-text messages the previous behavior is preserved.
On Microsoft SQL Server, primary key indexes were previously created as NONCLUSTERED. This was likely a legacy decision from the time when GIDs were UUIDv4 (fully random), which caused heavy fragmentation on clustered indexes during inserts. With UUIDv7 GIDs now being time-ordered, this fragmentation concern no longer applies.
NONCLUSTERED primary keys on SQL Server have two drawbacks: They result in a separate heap structure for the table data that must be joined on every lookup, and they can contribute to deadlocks under concurrent write load.
The fix is that newly created tables now use PRIMARY KEY CLUSTERED on SQL Server. Existing tables are not affected — only tables created after this change will have a clustered primary key.
8.4 Patch 6
The button that allowed changing the product of an existing service object has been removed. Selecting a product does much more than just setting a relation. It may create entries in the product class table, copies field values from the product to the service object, and behaves differently depending on whether the object is neutral, project-specific, or a product class variant. Changing the product after creation would only update part of this data while leaving other derived fields unchanged, resulting in an inconsistent state where the old product still showed the service object in its sub-list and the new product did not.
To assign a service object to a different product, a new service object must be created using the dedicated menu functions (neutral, project-specific, or product class).
8.4 Patch 6
8.3 Patch 19
Questionnaire questions marked with "Don't print" are now omitted when generating questionnaire reports. These questions are typically open-ended free-text inputs where printing all individual answers in a report makes no sense.
The DOC_INV=n filter was added to the PSA_QST_QUE data object in the following report loaders:
PSA_RPT_QST_BRT — data sheet at the questionnairePSA_RPT_ACT_REA_BRT — appointment visit reportPSA_RPT_PRS_EXT_BRT — data sheet of a personPSA_RPT_PRO_MKT_BRT — data sheet for a marketing projectThe background job "Mailbox: count unread mails" (PSA_MBX_CNT_UNR) periodically checks for unread emails and shows a notification dialog to the user. Users can now turn this notification off individually.
A new user-specific variable PSA_MBX_UNR_DSK_NFY ("Should a notification be displayed when new unread emails are found in the inbox?") controls the behavior. It is configurable in the “My preferences” dialog. Setting it to n suppresses the popup without affecting the unread mail count itself.
8.4 patch 10
Users can now export their favorites tree to a JSON file and import it again. This feature is available via the context menu on the top node (export all) or any selected sub-node (export subtree).
The exported JSON doesn’t contain system-owned fields (no primary key, no owner), so it can be imported by any user. The file includes metadata about when and by whom the export was created.
On import, the user is asked whether to insert only new entries or also overwrite existing ones. Matching is based on the favorite's name and key data (dialog, record ID, filter ID, etc.) rather than the primary key, which makes cross-user transfer work reliably.
Use cases
Customizing
PsaTreFvrExp, which is instantiated via PsaObjFac.newPsaTreFvrExp(). This class can be used for example, to implement a nightly backup job that exports all users' favorites automatically.When the repository class loader is refreshed (e.g. after deploying new IPL classes), any cached object factory instance that was created with the old class loader would throw a ClassCastException. This happened because the cached factory held class references from the old loader, while new instances were created via the refreshed loader — the two are incompatible for casting.
The fix adds a creation timestamp to the class loader. The object factory getter compares its own creation time against the class loader's — if the factory is older, it is discarded and a new instance is created transparently.
8.4 Patch 3
8.3 Patch 16
8.2 Patch 30
All new GIDs (global IDs / primary keys) are now generated as UUIDv7 instead of UUIDv4. UUIDv7 embeds a millisecond timestamp in the most significant bits, making new records sort chronologically and land in the same B-tree leaf pages as recent records rather than scattered randomly across the index.
Benefits
UUIDv7 values are fully compatible with the existing 32-character GID format.
8.4 Patch 6
The drill-down no longer automatically calculates and fetches results when a filter is changed. The default value of the variable PSA_DRL_DWN_AUT_FET has been changed to OFF, so results are only loaded when the user explicitly triggers the fetch. This avoids unnecessary database load when a drill-down is still configured but the result is not needed immediately.
Configuration
PSA_DRL_DWN_AUT_FET to ON to restore the previous automatic-fetch behavior.8.4 patch 3
Text modules are reusable text snippets that users can insert into emails and pin board messages. They are managed under “Administration > Service > Text modules” and organized into two levels: a group (first level) and a subject (second level). Each text module can be assigned a language.
When composing an email or a pin board message, a new button opens a modal tree selection dialog. The tree is structured by group and subject; selecting a leaf inserts the text into the text field.
Customizing
PsaTxtModChcTreApp.chc selection method accepts additional query parameters, allowing integrations to pre-filter the dialog — for example, to limit the tree to specific groups.New callAiAgent(PscUsxPar) hook in PsaFrmIpl, triggered by the AIA_PRC dialog function. It receives the request payload as a PscUsxPar — the request text (TXT), an optional HTM flag indicating whether that text is HTML, and an optional PEV ("prompt environment value") naming the environment value that provides the prompt template (falling back to PSA_CLOB_AIA_PROMPT). The prompt environment value name can be configured through the PAR property of a CLOB field's DAT tag, using the syntax PEV:=<name of environment value>. The hook returns an Optional<PscUsxPar> carrying the answer (TXT, optional HTM), or an empty Optional to signal cancellation.
Customizing
PSA_CLOB_AIA_PROMPT to provide a custom default prompt. Supported placeholders are ${language} (the supposed language of the text) and ${format} (the text format, such as HTML or plain-text).PSA_CLOB_AIA_PROMPT) in the DAT tag's parameter field, using the syntax PEV:=<name of environment value>.callAiAgent(PscUsxPar) in a custom dialog implementation for full control over the AI agent invocation.JR CRM Classic introduces a suite of AI-powered features that help users work more efficiently with customer data. These features cover text improvement, automated email drafting, meeting summaries, daily digests, and an interactive chat assistant — all powered by the GenAI service.
The following AI features are available directly within the CRM. You will find them as buttons or menu actions in the respective screens.
Where: Appointment, Task, Call
Improves the quality of text you have written in activity fields (visit reports, notes, emails). The AI corrects grammar and spelling, improves structure, and formats the result as HTML — while preserving all important content such as dates, to-dos, and commitments. The original language is always kept.
Where: Email
Generates a suggested reply for an email. The AI collects context from the conversation thread, contact details, company history, and recent activities to write a draft in your own style and language. The generated text is inserted into the email body for you to review before sending.
Where: Appointment
Converts a VTT meeting transcript (attached as a memo or file) into a structured HTML visit report. The AI labels speaker blocks and produces a clean summary that is written into the activity content field.
Where: Email
Extracts keywords from the current email and searches the knowledge base for relevant FAQ entries. If matching articles are found, the system asks whether to display them — useful for quickly finding answers to customer questions.
Where: Email
Reads the content of an email and asks the AI to extract a title, question, answer, and keywords for a new knowledge base article. The result pre-fills the FAQ creation dialog so you can review and save it in one step.
Where: Company, Opportunity, Quote, Order
Produces an AI briefing on a company or project. It collects up to one year of email conversations and recent appointments, then summarizes open topics, risks (budget, scope, escalation), internal to-dos, and customer sentiment from the perspective of an Account Director. The summary is shown in a dialog and can be saved as a memo linked to the company record.
Where: My Data, Internal Person
Generates a personalized daily overview of your assigned accounts. The AI scans recent customer communications and highlights relevant signals and developments. The digest is delivered as an in-app notification and saved as a memo. It can also be triggered manually from your personal view or an internal person record.
Where: Delivered via in-app notification (job output)
An executive-level daily summary across all accounts. The AI uses a two-pass approach. It first scans each company's recent communications for business risk signals (churn risk, budget and scope issues, escalation threats, upsell opportunities), then consolidates the findings into a prioritized report with recommended actions. Delivered as a memo to all subscribed management recipients.
Where: Delivered via in-app notification (job output)
A personalized compact briefing generated each morning for subscribed users. Covers the top 5 tasks for today, open follow-ups from the past week, top opportunities and quotes, and critical tickets. The briefing is role-tailored (sales, account director, or other) and includes deep links to the referenced CRM objects.
Where: Ticket
Aggregates the ticket subject, notes, pinboard, and linked activity history, then asks the AI to produce an HTML summary. The result is displayed in a read-only dialog for quick orientation on the ticket status.
Where: Internal messages, Pinboard
An AI chat assistant that answers CRM-related questions. Send a message to the SalesBot user or post a question on the pinboard — the bot reads your message, queries the CRM for context, and replies directly in the conversation thread.
The following jobs must be configured and activated in the job administration. All jobs can run with default settings.The entries below note any required setup.
| Job ID | Name | Notes |
|---|---|---|
AI_SALESBOT | AI: SalesBot | Requires a dedicated internal CRM user. Create an internal person with a login.The password can be intentionally set to an invalid value so the account cannot be used interactively. Enter this user in the job configuration. The job runs continuously and restarts automatically each day. |
AI_DAILY_DIGEST_SALES | AI: Daily Digest (Sales) | Runs once per day. Generates digests for all subscribed sales users. |
AI_DAILY_DIGEST_MANAGEMENT | AI: Daily Digest (Management) | Runs once per day. Delivers a consolidated report to all subscribed management users. |
AI_MORNING_BRIEFING | AI: Morning Briefing | Runs once per day in the morning. Delivers a briefing to all subscribed users. |
All functions use jr-auto/standard by default. The model for all functions can be configured by means of the variable PSA_GEN_AI_MODEL. To use a different model for a specific function, set the corresponding environment variable to the desired model identifier.
| Function | Variable |
|---|---|
| Beautify | PSA_GEN_AI_MODEL_BEAUTIFY |
| Email Suggestion | PSA_GEN_AI_MODEL_EMAIL_SUGGESTION |
| Meeting Transcript | PSA_GEN_AI_MODEL_MEETING_TRANSCRIPT |
| Search FAQs | PSA_GEN_AI_MODEL_SEARCH_FAQS |
| Create FAQ | PSA_GEN_AI_MODEL_CREATE_FAQ |
| Account Management Summary | PSA_GEN_AI_MODEL_ACCOUNT_MANAGEMENT_SUMMARY |
| Daily Digest: Sales | PSA_GEN_AI_MODEL_DAILY_DIGEST_SALES |
| Daily Digest: Management | PSA_GEN_AI_MODEL_DAILY_DIGEST_MANAGEMENT |
| Morning Briefing | PSA_GEN_AI_MODEL_MORNING_BRIEFING |
| Ticket Summary | PSA_GEN_AI_MODEL_TICKET_SUMMARY |
| SalesBot | PSA_GEN_AI_MODEL_SALESBOT |
All prompts are language-aware and can be customized. The system resolves a prompt in this order:
PSA_GEN_AI_PROMPT_<FUNCTION>_<POSTFIX> — if set, its value is used as the name of a BLOB that contains the custom prompt text.<FUNCTION>_<POSTFIX>_<LANGUAGE> (e.g., daily_digest_sales_usr_ger.txt) is searched.<FUNCTION>_<POSTFIX> (e.g., daily_digest_sales_usr.txt) is used as the final fallback.Prompts are stored as UTF-8-encoded text files (BLOBs). The standard prompts are shipped with the product and used automatically when no customization is present.
Prompt variables by function
| Function | Variable(s) |
|---|---|
| Beautify | PSA_GEN_AI_PROMPT_BEAUTIFY_USERPSA_GEN_AI_PROMPT_BEAUTIFY_APM_DEVPSA_GEN_AI_PROMPT_BEAUTIFY_CPD_DEV |
| Email Suggestion | PSA_GEN_AI_PROMPT_EMAIL_SUGGESTION_DEVPSA_GEN_AI_PROMPT_EMAIL_SUGGESTION_USERPSA_GEN_AI_PROMPT_EMAIL_SUGGESTION_CONTEXT |
| Meeting Transcript | PSA_GEN_AI_PROMPT_MEETING_TRANSCRIPT_DEV |
| Search FAQs | PSA_GEN_AI_PROMPT_SEARCH_FAQS_DEVPSA_GEN_AI_PROMPT_SEARCH_FAQS_USER |
| Create FAQ | PSA_GEN_AI_PROMPT_CREATE_FAQ_DEV |
| Account Management Summary | PSA_GEN_AI_PROMPT_ACCOUNT_MANAGEMENT_SUMMARY_DEV |
| Daily Digest: Sales | PSA_GEN_AI_PROMPT_DAILY_DIGEST_SALES_DEV |
| Daily Digest: Management | PSA_GEN_AI_PROMPT_DAILY_DIGEST_MANAGEMENT_DEVPSA_GEN_AI_PROMPT_DAILY_DIGEST_MANAGEMENT_PRE_DEV |
| Morning Briefing | PSA_GEN_AI_PROMPT_MORNING_BRIEFING_ROLESPSA_GEN_AI_PROMPT_MORNING_BRIEFING_DEVPSA_GEN_AI_PROMPT_MORNING_BRIEFING_USER |
| Ticket Summary | PSA_GEN_AI_PROMPT_TICKET_SUMMARY_DEV |
| SalesBot | PSA_GEN_AI_PROMPT_SALESBOT_CONTEXTPSA_GEN_AI_PROMPT_SALESBOT_DEV |
| Variable | Default | Description |
|---|---|---|
PSA_AI_SALESBOT_FUNCTION_FACTORY | — | Class name of a custom factory extending SalesBotFunctionFactory. Use to customize or extend individual AI functions. |
PSA_AI_MORNING_BRIEFING_MEMO_NAME | "Morning Briefing" | Name of the memo created by the Morning Briefing job. |
PSA_AI_ACCOUNT_MANAGEMENT_SUMMARY_MEMO_NAME | "Account Management Summary" | Name of the memo saved by the Account Management Summary function. |
PSA_AI_ACCOUNT_MANAGEMENT_SUMMARY_DATE_FIELD | PSC_CRE | Field in PSA_CON_ACT_REF used to sort and limit correspondence loaded for the summary. |
PSA_AI_ACCOUNT_DAILY_DIGEST_SALES_MEMO_NAME | "Daily Digest (Sales)" | Name of the memo created by the Sales Daily Digest job. |
PSA_AI_ACCOUNT_DAILY_DIGEST_SALES_DATE_FIELD | PSC_CRE | Field used to sort and limit correspondence for the Sales Daily Digest. |
PSA_AI_ACCOUNT_DAILY_DIGEST_MANAGEMENT_MEMO_NAME | "Daily Digest (Management)" | Name of the memo created by the Management Daily Digest job. |
PSA_AI_ACCOUNT_DAILY_DIGEST_MANAGEMENT_DATE_FIELD | PSC_CRE | Field used to sort and limit correspondence for the Management Daily Digest. |
All AI requests are automatically logged. The log is accessible under “Administration / Tools / GenAI protocol”.
The PsaGenAI library connects CRM server-side code to the JustRelate platform GenAI service. It supports multi-turn chat conversations with text, image, and file content, as well as tool/function calls.
Configuration
psa.iam.instance or variable PSA_IAM_INSTANCE.psa.gen.ai.url or PSA_GEN_AI_URL (default: the JustRelate Lambda endpoint).User-Agent header with psa.gen.ai.agent or PSA_GEN_AI_AGENT (default: Classic CRM).Supported language models
They may change over time but the service offers some aliases if you don't want to use a specific model:
jr-auto/fastjr-auto/standardjr-auto/powerfulBasic chat example
Tool calls
8.4 Patch 1
8.3 Patch 14
8.2 Patch 28
The web client moves from Eclipse RAP 3.29 to 4.7, which is a Jakarta-based platform (Servlet API 6.0). This is effectively two migrations at once, the RAP/RWT platform bump and the javax.servlet → jakarta.servlet namespace change, together with a move from Java 17 to Java 21. Nothing changes for end users; the payoff is a supported, current platform and a runtime that can be hosted on Tomcat 10.1 or newer. Tomcat 9.x cannot be used for this version.
WebP images are now supported throughout the web client. Whether used as article or service-object pictures, or embedded in rich text, WebP images now display just like any other image format.
The image conversion path was made considerably more robust at the same time (content-based format detection for mislabeled uploads, transparent decompression of gzip-compressed images, prompt release of decoder resources, and a configurable maximum image size).
Deployment note (image decoders and the shared JVM image registry)
The image readers are Java ImageIO plugins that register into the JDK's global image-reader registry, which is shared across all web applications running in the same servlet container / JVM. Two consequences follow:
The CLOB editor now offers an option to format individual table cells, so cell-level styling can be applied within a table instead of being limited to the table or paragraph as a whole.
If the Desktop Integration (PSADIM) fails to connect — because of a configuration error, a network problem, etc. — the user will now see more than just the red warning sign on the Web Client's login page. The Desktop Integration additionally opens a window with a more detailed error description, making it far easier to diagnose why the connection failed.
The CLOB editor supports placeholders: When a new email is composed from a template, placeholders such as {NAME} are resolved from the current (meta-)data — recipients, the sender's signature, etc. — as the template is applied. The editor offers two modes — a placeholder mode, where the literal placeholders ({NAME}, {TITLE}, …) are shown and can be inserted from a toolbar list or removed, and a value mode in which the resolved values ("Mr. Smith" instead of {NAME}) are shown as non-editable fragments. This change lets the user edit the value of such a fragment while in value mode.
Every backend node can now be assigned an individual ID that becomes part of each request URL. Load balancers and reverse proxies can read this ID directly from the URL to determine the backend node a request belongs to, and route it accordingly without having to inspect cookies or the session state. This makes sticky-session routing simpler and more robust in multi-node deployments.
The QuickFinder's field-selector dropdown can list a large number of fields, making the target field tedious to locate. The dropdown now carries a filter input ("Filter fields"): As you type, the list is narrowed down to the fields whose title matches your input. It filters the existing list rather than running a query — hence "Filter", not "Search". The filtered list is fully keyboard-navigable (arrow keys, Home/End/PageUp/PageDown, Enter to choose), and the input coexists with the menu's normal mouse interaction.
A tooltip of a numeric column may now contain statistics placeholders that are resolved on header hover: The referenced statistics are computed over the currently selected cells, formatted with the column's own number format, and inserted into the tooltip text. Supported placeholders:
| Placeholder | Alias | Meaning |
|---|---|---|
${sum} | — | Sum of the selected values |
${average} | ${avg} | Arithmetic mean |
${median} | ${med} | Median |
${minimum} | ${min} | Smallest value |
${maximum} | ${max} | Largest value |
${count} | ${cnt} | Number of selected values |
Only the placeholders actually present in the template are calculated (each at most once). If the tooltip contains no placeholder, the previous behavior is kept, i.e., the sum is appended to the column tooltip.
Table dialogs whose quick filters are backed by static, function-calling, persistent selector comboboxes now show a small overlay button (a reset arrow) next to the filter row. A single click resets all of these quick filters to their default values at once, triggering the associated function calls so the application server re-applies the default (unfiltered) selection. Since the selectors are persistent, the restored default state also carries over to the next time the dialog is opened.
This addresses the situation where predefined quick filters remain active across sessions without the user necessarily realizing it, making it look as if data were missing. The button offers a one-click way out without any side effects and without having to hunt down each individual filter.
Full Spanish, Portuguese and Polish variants were added. While reviewing the existing files, the French and Italian bundles were corrected: A few entries were still untranslated English (e.g. apply / reset). The base bundle was also aligned to match English exactly.
The CLOB editor now provides a default image alignment option in its toolbar. You can pick whether newly inserted images are aligned to the left, centered, or to the right, and the editor applies this alignment automatically to each image as you insert it, instead of always centering it. Explicitly aligned images and images in existing content are left untouched — the default only governs freshly inserted ones.
The chosen default is remembered per user, stored together with their other Web Client settings, so it carries over between sessions.
Pressing Tab inside the CLOB editor now indents the current paragraph like a word processor, and Shift+Tab reduces the indent again. Previously Tab either jumped to the next table cell or image, or moved the focus out of the editor entirely — behavior that felt unexpected when composing running text such as an email body.
For teams that rely on the old keyboard flow, a new setting, "Use Tab key to indent text", (enabled by default) turns the indentation behavior off again, restoring Tab as a navigation/focus key.
The web client has a new look, built on the refreshed JustRelate corporate design, which includes a new logo and favicon, the new brand orange, and an overall "lighter", less heavy visual appearance across the whole application. The application is lighter, calmer and more consistent: Windows, dialogs, tabs, menus and function bars now follow one common visual style, so the same elements look and behave the same way wherever you encounter them. Surfaces are clearer, lines are finer, and there is more room to breathe, which makes screens with a lot of content easier to scan and less tiring to work with all day.
Nothing about the way you work has to be relearned. All functions are where they were and work as before.
Branding – The logo and favicon were replaced with the new corporate artwork. The error and status pages (session ended, service unavailable, …) were converted to UTF-8 along the way.
Colors – The brand orange was refreshed to the bolder new tone and the related orange shades (used for pressed states, hovers and highlights) were re-derived from it, so the palette stays consistent. Many surfaces that used to be shades of grey are now white or a lighter grey — most visibly the function bar, the quick-finder area and the table row selection — which is the main driver of the lighter feel.
Finer lines and softer accents – Separator and border widths have been reduced (for example the tab separators and the toolbar separator of the external views went from 3 px to 1 px), the scrollbars are lighter, the window splitters ("sashes") are thinner, and several floating buttons are more subtle when idle. Floating messages now use a rounded "pill" shape matching the second-level tabs.
Top menu (ribbon) – The active top-menu item is now marked with a thin vertical border on each side that connects into a slim horizontal separator line between the top bar and the sub bar — the same visual language as the main tab system — instead of a filled background. This works both when the sub bar floats over the content and when it is pinned.
In use cases where the CLOB editor is shown without a toolbar, its formatting commands used to be out of reach. A floating toolbox now appears for those toolbar-less instances, carrying the same commands a regular toolbar would, so the full formatting options are available without permanently occupying space. It shows smartly — only while the editor is focused and in edit mode — and can be suppressed per field with the "Do not show toolbox" tag style for cases that should stay strictly toolbar-less.
In situations in which the CLOB editor is shown without a toolbar, the only way to open the extended (maximized) editor used to be the F2 key which is hard to discover and unreachable by the mouse. A small arrow button now appears in the editor's top-right corner in those toolbar-less instances, giving the maximize action a visible, clickable affordance.
The CLOB editor comes in a basic and a full-featured ("extended") variant. The maximized editor is always the full one; an inline editor only gets the full toolbar in specific cases (a full-toolbar tag style or a modal dialog with placeholders). Power users who prefer the complete toolbar everywhere had no way to get it inline.
A new per-user option, "Always use the full-featured editor" (in the "More options" settings, next to the Tab-indent option) lets them opt in. If enabled, inline editors are created with the full toolbar too, not only when maximized. The choice is persisted per user, alongside the other editor preferences (spell checking, default image alignment).
This is an admin or DevOps feature (not visible to end users): The web client already supported "configuration by environment" for global configuration and login sets, which is convenient in container deployments where a provisioning script is easier to manage than config files. Logging was the one subsystem this did not cover. It does now, which is useful both for containers and for turning a debug logger on in production without editing files (the case that motivated it).
Hands-on for operators
All names start with PISASALES_WEBCLI_LOG_:
| Environment value | Meaning |
|---|---|
PISASALES_WEBCLI_LOG_LEVEL_ROOT | Root logger level (OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL). Defaults to WARN. |
PISASALES_WEBCLI_LOG_LEVELS | Per-logger levels as a comma-separated logger=level list, e.g. de.pisa.webcli.thm=DEBUG,de.pisa.webcli.vws=DEBUG |
PISASALES_WEBCLI_LOG_DIR | Override the directory the log files are written to. |
PISASALES_WEBCLI_LOG_STDOUT | Set to true to also write the log to the console (stdout), which most container log collectors expect. |
PISASALES_WEBCLI_LOG_RECREATE | Set to true to re-apply the environment values to the logger configuration on the next start or configuration reload. |
An invalid value (an unknown level, a malformed entry) is ignored with a warning, so a typo can never break logging startup.
How the values take effect
The values are applied to the logger configuration when it is first created. The environment provides the initial configuration, and an administrator can still adjust logging at runtime on the admin page. A runtime change is never overwritten by the environment. On a container, the configuration is re-created on every start, so changed environment values are picked up automatically. On a persistent installation (a VM or physical machine), the existing configuration is kept across restarts. To re-apply changed environment values there, set PISASALES_WEBCLI_LOG_RECREATE=true. This is honored both at startup and on an environment-driven configuration reload, so the values can be re-applied without a full restart.
An admin feature: The "Force settings" section of the login-set editor lets an admin push a batch of application-configuration flags (Desktop/Browser/Message view visibility, QuickViews, the top ribbon's pinned state, the push notification service, and so on — 16 flags in total) onto sessions using that login set. Most of these flags are applied once, right after login, gated by an update time stamp that must be newer than the settings a session already applied. The push-notification-service flags are instead consulted live whenever the push service initializes. Either way, every flag used to be a plain on/off value, so forcing one setting forced all of them. There was no way to say "leave this one alone".
Every flag is now tri-state: on, off, or unset. In the editor, the corresponding checkbox cycles from indeterminate to checked to unchecked, and then indeterminate again. Leaving a flag indeterminate means that the login set does not touch it at all; whatever the user (or a previous override) already had in place stays untouched. Only the flags actually switched on or off take effect.
"Persistent tab items" and "Persistent sash proportions" join the same mechanism. These two settings predate the current per-user configuration system and used to live only on the login set itself, with no independent per-user default and no way to leave them unset. They are now regular per-user settings — applied through the same time-stamp-gated mechanism as most of the 16 flags above — that a login set can optionally override through the same tri-state checkboxes, consistent with everything else in that section.
Two settings in the user settings dialog ("More options" section) that existed before but had no visible on/off switch for the user — "Persist tab item selection" and "Persist sash proportions" — are now available directly there.
"Persist tab item selection" remembers the tab that was open in a dialog and selects it again the next time you open that dialog. "Persist sash proportions" remembers the size you gave to a dialog's table area compared to its details form, and restores that proportion the next time you open the dialog, instead of resetting it to the default split every time.
Both settings can also still be preset (or forced) by an admin through the login-set editor.
The "Always use the full-featured editor" per-user option joins the login-set override mechanism: An admin can now preset it for users of a given login set, or leave it untouched so each user's own choice is kept due to the same tri-state checkbox pattern as the other overridable settings in that dialog.
Cockpit/dashboard charts used to be generated as PNG images on the application server and shipped to the browser as pictures. The application server now delivers the underlying chart data as JSON, and the web client renders it itself using Apache ECharts: pie, bar, line, stacked bar, combined line/bar, gauge, and both funnel chart types (dynamic and static), including a three-column funnel layout (name / count / value) and a bold summary row, matching the Windows client. Number formatting (short/long/full/percent, currency, pre-scaled values with a literal unit like "T€"), legends, value labels and a "no data" message all follow the JSON contract. Clicking a chart element (a bar, pie slice or funnel segment) triggers the same hyperlink action a click on the whole chart already did with server-rendered images.
A new hideable side view, "AI Assistant", joins the existing "Desktop" and "Browser" side views. From the client's perspective, it is just another server-rendered side view. The client does not interpret its content, it only provides the view itself, its toggle button and its menu entry.
The AI Assistant feature is implemented entirely by the application server. Both a recent web client and a recent application server version are required to use it. An older server simply leaves the feature unavailable, with no error.
The web client no longer offers a portal mode. For use cases like questionnaires and portals, JustRelate provides a much better solution, a dedicated, powerful, modern and good-looking portal app based on the Web Builder. Please use it instead.
Customers still requiring a web client in portal mode can keep running an older web client version. They should plan to migrate to the portal app as soon as possible because older versions do not receive the improvements of newer ones.
The CLOB editor has received a toolbar button to view and edit the raw HTML source of the current content directly. It is disabled while the editor is in plain-text mode (there is no HTML source to edit there).