Reduces job processing time by avoiding repeated TCP connect, TLS
handshake, and SMTP AUTH on every email sent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update testBlockedAccount and testSelfBlockedAccount to expect 403
instead of 401 for blocked user responses. These were missed in the
previous test assertion update.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Change expected status code from 401 to 403 for USER_BLOCKED errors
to match the semantic change in error codes.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update USER_BLOCKED from 401 to 403 and simplify description
- Update GENERAL_RESOURCE_BLOCKED from 401 to 403
Rationale: 403 Forbidden is the correct HTTP status for authorization
failures where the user is authenticated but not permitted access.
401 Unauthorized is for authentication failures.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Optimize updateDocument() calls across the codebase to pass only changed
attributes as sparse Document objects rather than full documents. This is
more efficient because updateDocument() internally performs array_merge().
Changes:
- Updated 58 files to use sparse Document objects
- Added Performance Patterns section to AGENTS.md with optimization guidelines
- Applied pattern to Workers, Functions, Sites, Teams, VCS modules
- Updated app/controllers/api files (account, users, messaging)
- Updated app infrastructure files (realtime, general, init/resources, shared/api)
Exceptions maintained:
- Migration files (need full document updates by design)
- Cases with 6+ attributes (marginal benefit)
- Complex nested relationship logic
- Remove specific index length number from testPatchAttribute assertion
since the value differs between shared/non-shared table modes (767 vs
768) and the console API returns the console project's value, not the
user project's
- Use getLastEmailByAddress in testPasswordRecoveryUrlParams to avoid
retrieving emails from parallel test classes sharing the same maildev
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, the updateProjectAccess method updated the database with the new
accessedAt timestamp but did not update the in-memory project document. This
caused the if statement to constantly evaluate to true on subsequent calls,
triggering unnecessary database updates.
- Fix getMaxIndexLength() fallback from 768 to 767 to match MariaDB's
actual InnoDB index key limit
- Add retry logic to getConsoleVariables() to handle intermittent 401s
- Add retry logic to API key creation in ProjectCustom to prevent
cascading 401 failures in test methods
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use getLastEmailByAddress for SMTP tests instead of getLastEmail(2) to
avoid shared mail server state issues under parallel execution
- Add retry logic to setupProject, setupProjectData, and
setupScheduleProjectData for intermittent 401 errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
getRoot() now retries up to 5 times with session verification to handle
race conditions when multiple paratest workers initialize simultaneously.
Previously, if account creation or session creation failed under load,
all subsequent test requests would fail with 401.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stale in-memory project documents in ScheduleBase (and request-scoped
copies in api.php/general.php) were overwriting current DB state when
updateProjectAccess triggered. Because Database::updateDocument uses
array_merge with the passed document taking priority, cached projects
missing recent OAuth provider changes would silently disable them.
Now fetches a fresh project document from the DB before writing, so only
accessedAt is updated without clobbering other fields.