Renames the actor identity constants used by the audit/auth flow:
- ACTIVITY_TYPE_USER -> ACTOR_TYPE_USER ('user')
- ACTIVITY_TYPE_ADMIN -> ACTOR_TYPE_ADMIN ('admin')
- ACTIVITY_TYPE_GUEST -> ACTOR_TYPE_GUEST ('guest')
- ACTIVITY_TYPE_KEY_PROJECT -> ACTOR_TYPE_KEY_PROJECT ('keyProject')
- ACTIVITY_TYPE_KEY_ACCOUNT -> ACTOR_TYPE_KEY_ACCOUNT ('keyAccount')
- ACTIVITY_TYPE_KEY_ORGANIZATION -> ACTOR_TYPE_KEY_ORGANIZATION ('keyOrganization')
Values are unchanged. Call sites updated in:
- app/controllers/shared/api.php
- src/Appwrite/Platform/Workers/Audits.php
Audit payload key rename (userType -> actorType) and utopia-php/audit
bump will land in a follow-up PR.
BREAKING CHANGE: ACTIVITY_TYPE_* global constants are removed. Any
downstream extension or plugin importing those names must be updated
to the ACTOR_TYPE_* equivalents.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adopts the new safe-wildcard dispatch primitive from
utopia-php/http#feat-safe-wildcards. Http::execute() is now the
re-entrant dispatch entry point and Http::match() is pure (returns
?RouteMatch). The removed Http::getRoute()/setRoute(),
Route::getMatchedPath(), Route::getPathValues() callsites are migrated
to the new API.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The DELETE_TYPE_TRANSACTION constant was 'transaction' (singular), so
the worker's inner switch on $document->getCollection() (which returns
'transactions') never matched and every transaction deletion fell to
the default branch, logging "No lazy delete operation available for
document of type: transactions". Renamed to DELETE_TYPE_TRANSACTIONS
to align with every other constant used in that switch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Span attribute keys are now snake_case with dots only for child
relationships. Worker span lifecycle moved to app/worker.php; selective
trace filtering moved to the exporter sampler in app/init/span.php so
handlers only call Span::add.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add skipFilters to Reports/Get.php (was the only endpoint still
triggering the full N+1 subquery cascade)
- Scale CTA batch limit dynamically (insightCount * MAX_CTA_COUNT)
instead of fixed APP_LIMIT_SUBQUERY to prevent silent truncation
- Revert deleteReport to callback-based pagination so CTAs are not
orphaned when a report has more than APP_LIMIT_SUBQUERY insights
- Add explicit prefix lengths (700) to _key_project_resource and
_key_project_parent_resource indexes to stay under InnoDB 3072-byte limit
- Validate CTA service/method against ADVISOR_CTA_SERVICES and
ADVISOR_CTA_METHODS enums in the CTAs validator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix N+1 in Reports/XList (51→4 queries) via skipFilters + batch fetch
- Add skipFilters to Reports/Delete and cursor fetch (avoid loading all
nested insights/CTAs just for ownership check)
- Fix N+1 in deleteReport worker (flat CTA deletion instead of per-insight)
- Add advisor entity cleanup on project deletion (reports, insights, CTAs)
- Remove resourceInternalId, parentResourceInternalId, $permissions from
Insight response model (internal IDs leak DB internals, permissions unused)
- Remove dead subQueryInsightCTAs filter registration
- Remove stale enum-value comments from platform schema
- Fix _key_dismissedAt index to include projectInternalId
- Fix scope category from 'Other' to 'Advisor'
- Switch action base class from Utopia\Platform\Action to Appwrite\Platform\Action
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adopts the new split DI containers in utopia-php/http: `resources()` for
boot-time wiring (shared across requests) and `context()` for per-request
state. Replaces the removed `getResource()`/`setResource()`/`getContainer()`
helpers throughout the HTTP entry point, controllers, GraphQL layer, and
installer.
Bumps the dependency chain accordingly: utopia-php/http to the dev branch
(aliased to 0.34.25 to satisfy platform's exact pin), servers 0.4.*,
queue 0.18.*, and pulled-along cli/platform/database upgrades.
Also tightens app/init/resources/request.php by collapsing single-return
factories to arrow functions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The module's namespace and directory now match the top-level service
name (`advisor`) instead of one of its resource names (`insights`):
- src/Appwrite/Platform/Modules/Insights -> .../Modules/Advisor
- src/Appwrite/Insights -> src/Appwrite/Advisor
- tests/unit/Insights -> tests/unit/Advisor
- Route group label flipped from `'insights'` to `'advisor'`
- Section-header comments aligned
Resource names (`insights`, `reports`, `insightCTAs`) and the
`Insight*`/`Report` response models stay — those are the resources the
service exposes, not the service itself.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`getDatabasesDB` used `??` to fall back from a database doc's `database`
attribute to the project DSN, but `??` only triggers on null. Migration
destinations end up with an empty-string `database` (the value is copied
from the source DB but isn't a valid DSN on the destination's pool),
which slipped past the fallback and surfaced as a 500 with
`new DSN('mysql://')` in the catch block. Use elvis so empty strings
fall back too.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves conflict in app/init/constants.php (kept 4327 cache buster, took 1.9.4 stable version).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
target stores free-form URLs or resource IDs. URLs in the wild can
exceed the prior 2048-char cap, so switch the column to VAR_TEXT
(65535). The _key_project_target index already declares an explicit
700-char prefix length, so indexing still works on both MariaDB and
MongoDB.
Bump APP_CACHE_BUSTER for the schema change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch markdown summaries, JSON CTA params, and the embedded
insights/ctas subQuery payloads from sized VAR_STRING to VAR_TEXT.
None of these fields are indexed and they all hold free-form data, so
removing the artificial size cap means we never have to revisit the
limit when an analyzer surfaces a longer report.
- reports.summary, insights.summary: markdown, no upper bound enforced
- reports.insights, insights.ctas: subQuery virtuals carrying full
child rows
- insightCTAs.params: JSON parameter blob for arbitrary CTA actions
Bump APP_CACHE_BUSTER for the schema change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>