Move the collection mapping query from inside the Metadata decorator to
the getDatabasesDB resource factory. This avoids decorator-level
database queries that can fail in various contexts and cause cascading
issues.
The mapping is loaded once when getDatabasesDB creates the database
instance, and the results are passed to the Metadata decorator via
setCollectionId(). The decorator itself is now stateless with respect
to database queries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace findOne per decoration with a single find query that loads all
collection sequence→ID mappings on first access. Caches the result for
the lifetime of the decorator instance. Silently falls back to internal
names on failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The decorator receives _metadata documents where $id is the internal
collection name (e.g. 'collection_5'), not the user-facing collection
ID. The old processDocument() got the user-facing ID from the endpoint.
Fix: extract the sequence number from the internal name, look up the
Appwrite collection document by $sequence to get the user-facing $id,
and cache the mapping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Includes loose comparison (!=) for tenant checks in Collections.php to
handle int/string tenant value mismatches, and PHPStan type assertions
for Document constructor calls.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates utopia-php/database with fix for inline relationship data
without $id not being auto-converted to Document objects. The
Relationships hook now converts associative arrays to Documents before
type-checking, allowing auto-ID generation to work.
Also increases testEventTrigger timeout to 120s and Realtime concurrent
test timeout to 90s for CI resilience.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Float attributes created via API use type 'double' (ColumnType::Double)
since the Float/Create endpoint was updated. The format registration
must match to pass format validation during attribute creation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use Utopia\Query\Schema\ForeignKeyAction instead of the non-existent
Utopia\Database\ForeignKeyAction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Functions testEventTrigger: increase assertEventually from 20s to 60s
to accommodate shared mode queue latency and cold starts
- Realtime testConcurrentRealtimeTrafficCoroutines: already has 45s
WebSocket timeout and TimeoutException handling for CI resilience
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The updateRelationship() method expects ForeignKeyAction enum but
Action.php was passing the raw string from options. Use
ForeignKeyAction::from() to convert.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Metadata decorator: look for relatedCollection inside options array
since new Attribute format nests it there
- Skip decorators during silenced operations to prevent $databaseId etc.
from leaking into internal write operations
- Fix aggregate test queries to use Query::count('*', 'total') instead
of Query::count('total') which treats 'total' as a column name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- UserEvents hook: set project on events before triggering to fix null
project in function worker queue messages. Also use $this->project
directly for console check instead of $this->events->getProject()
which was null.
- Metadata decorator: stop removing $collection from documents since
the Response model layer already handles this in filter(). Removing it
in the decorator broke updateDocument and cursor pagination.
- Update utopia-php/migration to feat-query-lib branch with ColumnType
enum, Attribute objects, and removed Database::VAR_* constants.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Float attributes must use ColumnType::Double (value 'double') to match
the existing AttributeFloat response model condition and Range validator.
ColumnType::Float (value 'float') caused "Missing model" errors and
Range validation failures.
Also reverts Collection/Table response model rule keys from $databaseId
back to databaseId since the Metadata decorator skips _metadata
documents — collection responses use the non-prefixed key.
Updates utopia-php/database with Attribute validator Float case fix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
castingAfter must run unconditionally in createDocument to convert
adapter-specific types (MongoDB UTCDateTime) to PHP types.
Also removes hardcoded project ID check in Executions worker that was
preventing execution upserts for a specific project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Metadata decorator now skips _metadata collection documents to prevent
injected $databaseId/$collectionId attributes from leaking into SQL
UPDATE statements via getAttributes()
- Add Tenancy hook to dbForProject in shared mode (was missing, causing
401 on session verification)
- Update Collection/Table response models to use $databaseId with $
prefix matching the decorator
- Update utopia-php/database with MongoDB tenant null filter fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The V17 filter now correctly parses cursorAfter/search/isNotNull queries
with their full parameters (attribute, values) instead of stripping them
to method-only objects.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
V17 filter's str_contains($method, '.') throws when $method is a Method
enum. Guard with is_string() since enum cases never contain dots.
Proxy test: delete rule before site to avoid cascade-delete race.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
V17 request filter switch compared raw strings against Method enum
cases which never matched in PHP 8.1+. Use Method::tryFrom() to convert
the parsed method string to the enum before the switch.
Also updates utopia-php/database with skipValidation for internal
metadata document updates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use PermissionType->value when constructing Permission objects (Documents/Create,
Upsert, Transactions/Create, Storage/Files/Create)
- Convert Method enum to string in Realtime adapter implode and interpolation
- Use Attribute/Index object property access in VectorsDB Collections/Create
- Update utopia-php/database with Structure Float case, TenantFilter alias fix,
and Document::getTenant() type cast removal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Handles numeric string (millisecond timestamp) values in castingBefore
by passing them directly to UTCDateTime instead of NativeDateTime.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Query::groupByType() now returns a GroupedQueries readonly class instead
of an associative array. All bracket access ($grouped['filters'], etc.)
must use arrow syntax ($grouped->filters).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Pool adapter was only syncing write hooks (Permissions, Tenancy) for
plural document operations (createDocuments, updateDocuments) but not
singular ones (createDocument, updateDocument). This caused permission
rows to never be inserted for single-document creates, making newly
created users invisible to subsequent queries on SQL databases.
Also removes stale PHPStan baseline entries and fixes redundant null
coalesce in FunctionCache.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When --release=yes, the Appwrite spec version is not needed since
the release flow uses the SDK version from config. This moves the
version prompt and validation behind a !$createRelease guard and
hoists the release block before the spec/SDK generation setup.
Revert auth types in Bulk/Upsert.php back to [AuthType::ADMIN, AuthType::KEY]
and remove duplicate query filter in Databases/XList.php that were accidentally
introduced during the 1.9.x merge.
https://claude.ai/code/session_01JLPDurUgyj7qViA8JqQFTH
remove duplicate inject('user') from XList in DocumentsDB/VectorsDB
- DocumentsDB and VectorsDB Transactions/Operations/Create.php were
missing ->inject('user') needed by parent action method
- DocumentsDB and VectorsDB Collections/Documents/XList.php had
duplicate ->inject('user') calls - removed the extra one
https://claude.ai/code/session_01JLPDurUgyj7qViA8JqQFTH