In filter bucket mode a bucket's search was written into the shared search options and never reset, so buckets processed afterwards (random map order) inherited it.
TaskCollection.ReadAll built the saved filter's collection but recursed with the request search only, so filters.s was never applied. The stored search now takes precedence, matching view and bucket filter searches.
Moving a project to a position below 0.1 respread the positions of all
sibling projects on the instance. It now only touches the siblings the
user can write, plus the moved project itself.
The background of a new project is only ever set by the background
endpoints. Duplicating a project now hands the source background to the
copy step explicitly instead of relying on the field surviving creation.
The user data export embedded every related task in full, repeating its
description once per relation. Related tasks are now exported as id and
project id only, since every related task is part of the export anyway.
The importer resolves such references across all imported projects and
creates relations once every project exists, so relations between
projects survive the round trip instead of duplicating the related task.
Exports with the full related task shape import as before.
- Reject a config that maps a column more than once, already when the
import is started or previewed.
- Import repeated labels of a row once and reject rows with more than
MaxLabelsPerTask (100) labels.
- Count items while converting rows so a file over the import item limit
fails before the whole structure is built.
- Walk mappings sorted by column so a row only visits the cells it has.
Every VALARM repeats the task title and the output was built with string
concatenation, so rendering cost grew quadratically with the number of
reminders. Build it with a strings.Builder instead.
Tasks may now have at most MaxRemindersPerTask (100) reminders and a
title of at most MaxTaskTitleLength (1000) characters, checked through
v1, v2 and CalDAV. On update the reminder limit only applies when the
count grows and the title limit only when the title changes, so existing
tasks stay editable.
The business day offsets in the date values of a task or time entry
filter may now add up to at most MaxDatemathBusinessDays (10000). Larger
filters are rejected with the invalid filter value error before any value
is evaluated. The frontend date math parser applies the same limit.
Address PR Swarm lock-order decision across task writes, restoration, and project/user purges. Reject moves discovered after view locks without acquiring views out of order.
Covers comments, attachments, labels, assignees, relations, reactions and task duplication. Assignee access is now checked against the project the task is in after the lock.
Implement the approved last_purged_at decision with an advancing purge generation so same-second purges invalidate old tokens and full resync tokens remain usable.