Importing from an old help desk system: old reporters and agents
I'm looking at importing tens of thousands of support cases from an old help desk system.
I want to store them in a cloned copy of my production (live) help desk in YouTrack. The cloned copy should be visible only to current help desk agents.
If a user submitted a case in our old system years ago, then submits a new one using the same address in YouTrack now, they should not be aware of the existince of the earlier case. The reason is that I cannot guarantee proper ownership of the credential. That is, while user@ibm.com ten years ago may be the same as user@ibm.com today, quacker99@gmail.com could be a different person.
Will this be feasible?
Also, I want to set the Assignee field to reflect the old agent, even though they're no longer agents. Will this be a problem with the quantity of help desk agents allowed to be agents in my production, live help desk project?
Please sign in to leave a comment.
Hello!
Reporters in YouTrack can only see their own tickets, so ordinarily there would be no visibility issue. The problem is that if someone submits a new ticket using the same email address as an old imported case, YouTrack can merge the old and the new user, and they'd see both the new and historical tickets together.
To prevent this, set the archive project's reporter access to Restricted and leave the authorized reporters list empty. Reporters who aren't explicitly authorized can't access the project at all, so old cases remain invisible to them even if their email matches. If you don't need any helpdesk-specific features in the archive (email channels, online forms), a standard project is an even simpler option. Reporters have no access to standard projects at all.
Setting someone as Assignee on a historical ticket doesn't make them a helpdesk agent. The agent count for your live helpdesk project is determined solely by users who have the Agent user type, which must be explicitly assigned by an admin. Users referenced only as Assignees in archived tickets won't have this type and won't affect your production project's agent count.
If those old agent accounts don't already exist in your YouTrack instance, they'll be created as Standard users during the import (or auto-banned if the standard user license limit is exceeded). Either way, they won't affect the agent count.
For the import itself: YouTrack has built-in migration tools for some systems (Zendesk, Jira Service Management, GitHub, and others). For other systems, CSV/XLSX or a custom import script would be the way to go.
I hope this helps. Have a nice day!
In fact, setting the old system archive as a regular project is probably the right way to go.
The old system can only be accessed by accessing its' SQL Server database directly. So far I'm using an ETL tool to map from that database to individual JSON files, one per issue. So far they basically look like this. I will need the import script to read each JSON file from a directory on the server and create the issue. Does this look okay so far?
```json
[
{
"$type": "issue",
"id": "9-5968",
"key": "FPX-5968",
"fields": {
"summary": {
"type": "string",
"value": "The summary of the issue"
},
"description": {
"type": "text",
"value": "Description:\n\n I'm having a problem with your product."
},
"author": "joe@customer.test",
"created": "2006-06-20T21:27:47",
"State": {
"type": "string",
"value": "Resolved"
},
"Assignee": {
"value": "alice.smith@ourcompany.test"
},
"comments": [
{
"author": "alice.smith@ourcompany.test",
"timestamp": "2006-06-22T16:15:32",
"text": "Dear Joe,\n\nThank you for letting us know."
},
{
"author": "joe@customer.test",
"timestamp": "2006-06-22T17:41:33",
"text": "Hey, Alice, that worked. Thanks!"
},
{
"author": "alice.smith@ourcompany.test",
"timestamp": "2006-06-26T17:01:49",
"text": "Dear Joe, You can fix it by turning it off and on again."
}
],
"Custom field 1": "foo bar",
"Query Type": "Bug report",
"Product": "Microsoft Word"
}
},
{
"$type$": "attachment",
"name": "foo.xml",
"mimeType": "text/xml",
"content": "PGZvby8+"
}
]
```
Hello!
A few things to fix:
"$type"/"$type$"wrappers: please remove them. The Issue type only hasid,key,fields, andhistory, no type envelope."timestamp"should be“created”:timestampis a property of HistoryItem. Comments extend SubItem, which defines the timestamp field ascreated.Statefield type: should be{"type": "state", "value": "Resolved"}, not"string".Assigneeis missingtype: should be{"type": "user", "value": "alice.smith@ourcompany.test"}.fields.attachments[]on the issue, not as sibling objects in the array. The filename key isfileName, notname(see Attachment). Binary content doesn't go in the JSON; return it fromgetAttachmentContent()instead (see AttachmentContentWithMetadata).I recommend checking the Demo Import Script, as it shows the correct format for different imported items.
I hope this helps. Please feel free to reach out anytime if any questions arise.
I don't see that the Demo Import Script shows attachments. Does it?
What's the intention, that each issue have an array of attachments, then the import script fetches each one from the old system?
Hi!
You're right, the demo client doesn't actually exercise attachments. It defines a stub
getAttachmentContent()method, but the bundled demo-issue.js data file has noattachmentsfield, so the runtime never calls it.Yes, exactly. Each issue declares its attachments as metadata under
fields.attachments[](id, filename, author, created, mimeType, optional contentUrl), and the runtime callsgetAttachmentContent(project, document, attachment)once per attachment to fetch the bytes. The return shape is{ data, metadata }, wheredatais the binary content (base64-encoded string or a response stream) andmetadatacarries at least themimeType.You can find the full field reference here:
I hope this helps. Have a nice day!
There seems to be some overlap between Import-Attachment and Import-AttachmentContentWithMetadata. For example, I see mimeType both on Attachment itself as well as within the metadata object of the AttachmentContentWithMetadata.
If one were to add an attachment array to demo-issue or (demo-helpdesk-issue) in your youtrack-demo-client, which of these two forms should the objects take?
Hi!
The two types you're looking at cover different parts of the import flow, so the
mimeTypeoverlap is not redundancy. They're separate contract points.Import-Attachmentis what goes infields.attachments[]on each issue in your data. HeremimeTypeis a top-level field on the attachment object. This is your Format A:Import-AttachmentContentWithMetadatais what yourgetAttachmentContent()method returns, the actual file bytes. Here `mimeType` goes inside a nested `metadata` sub-object. This is your Format B:On your
idquestion: it is optional. If you omit it, the runtime uses an internal placeholder for that attachment. That's fine for a one-shot historical migration. If you plan to run continuous imports (re-importing updated issues from the source system as they change), providing a stable unique ID per attachment matters, as the runtime uses it to tell which attachments have already been imported. The source system's own attachment ID is the natural choice.For the full field reference for both types, see the Import API Reference. The Demo Import Script also shows the
getAttachmentContent()return structure if that helps as a reference point.Let me know if you have any more questions!