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.
Indexes come from an atomic counter increment instead of MAX(index)+1, so
retired indexes are never reused. Client-supplied indexes are ignored;
import and duplication keep presets above the old high-water mark. Moving
a task records its old address as an alias; the task row is read under a
row lock so concurrent moves serialize. Task bucket inserts are chunked
since whole batches now go through one create.
Creates up to 100 tasks in one project atomically. One project write
check covers the batch; any invalid task rolls the whole batch back
with error 4031 naming the offending payload index, and an
invalid batch size returns 4030. The 1..100 bound is declared as
minItems/maxItems in the schema (pinned to the constant by a test) with
the model check as backstop for non-HTTP callers. Payload positions are
zeroed — positions are always calculated server-side.