Commit Graph
852 Commits
Author SHA1 Message Date
Jake BarnbyandClaude Opus 4.7 b747c97561 fix(advisor): address review comments on scopes and schema
- Register dedicated reports.write scope and switch deleteReport to it
  so cloud can issue narrowly-scoped delete keys without granting
  insights.write.
- Make insights.parentResourceInternalId optional with null default to
  match its companion parentResourceType/parentResourceId fields and
  unblock insights with no parent (e.g. database-level performance
  insights).
- Tighten Insight.reportId model description: insights always belong to
  a report, ad-hoc insights are not supported.
- Add reports.write to default test API key and admin role so existing
  e2e tests using serverHeaders() can hit the delete endpoint.
- Bump APP_CACHE_BUSTER for the schema change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 12:18:39 +12:00
Chirag Aggarwal 34075322d7 Migrate mails and messaging queues to publishers 2026-05-08 14:32:11 +05:30
copilot-swe-agent[bot]andabnegate 56b9de097f fix(advisor): restore report delete with async nested cleanup
Agent-Logs-Url: https://github.com/appwrite/appwrite/sessions/6496395d-5cbf-42ba-a3e0-d3c9e6ca901c

Co-authored-by: abnegate <5857008+abnegate@users.noreply.github.com>
2026-05-08 06:54:49 +00:00
copilot-swe-agent[bot]andabnegate 6d0eab2583 refactor(advisor): make insights API read-only in CE
Agent-Logs-Url: https://github.com/appwrite/appwrite/sessions/8d7897b5-ac68-487d-954a-be717380bf66

Co-authored-by: abnegate <5857008+abnegate@users.noreply.github.com>
2026-05-08 06:07:23 +00:00
Chirag Aggarwal 8ebf4fee46 Use storage cache callback max age 2026-05-08 11:18:55 +05:30
Chirag Aggarwal 9337daf7ac Preserve default storage cache hit max age 2026-05-08 11:15:17 +05:30
Chirag Aggarwal bf76736971 Split storage cache control context 2026-05-08 09:57:33 +05:30
Chirag Aggarwal 6abd88b8f1 Type storage cache control config 2026-05-08 09:44:00 +05:30
Chirag Aggarwal 7b5a5b8d19 Rename storage cache control hook 2026-05-08 08:44:35 +05:30
Chirag Aggarwal 20ab5b026e Add cached response cache-control callback 2026-05-08 08:33:37 +05:30
loks0nandClaude Opus 4.7 7d0843cc7f Migrate queueForBuilds to publisherForBuilds pattern
Replaces the stateful Appwrite\Event\Build queue class with a stateless
BuildPublisher and BuildMessage DTO, matching the publisher pattern used
by audits, certificates, executions, migrations, screenshots, stats, and
usage. Call sites now enqueue messages directly instead of mutating a
shared event object and relying on the API shutdown hook.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 13:23:21 +01:00
Jake Barnby a8f33ab964 Merge branch '1.9.x' into presence-api 2026-05-07 19:13:57 +12:00
Matej Bačo ec927104fe Merge pull request #12221 from appwrite/fix-variables-api-feature-parity
Feat: Variables API feature parity
2026-05-06 11:27:32 +02:00
Jake Barnby 6c6782dd28 Merge remote-tracking branch 'origin/1.9.x' into pr-12194-feat-insights-module
# Conflicts:
#	app/config/scopes/project.php
2026-05-06 20:33:40 +12:00
Matej Bačo 1ccf058c14 Fix failing tests 2026-05-06 10:19:30 +02:00
Jake BarnbyandClaude Opus 4.7 c5dfc42a60 refactor(insights): rename ctas collection to insightCTAs
Disambiguate the platform-level collection name. Field/request-param
remains `ctas` (the embedded array on the insight response).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:12:17 +12:00
Jake BarnbyandClaude Opus 4.7 5404bfec75 refactor(insights): promote CTAs to own collection with backref
Embedding CTAs as a 16384-byte JSON blob on `insights` was the wrong
shape — they're real documents with their own lifecycle. Move them out.

Schema:
- New platform `ctas` collection. Each row carries `projectInternalId`,
  `projectId`, `insightInternalId`, `insightId` (backref), plus the
  CTA fields: `key`, `label`, `service`, `method`, `params`.
- Indexes: `(projectInternalId, insightInternalId)` for the subquery
  lookup and a UNIQUE `(insightInternalId, key)` so the per-insight
  uniqueness invariant lives at the DB layer (not just in PHP).
- The `ctas` field on `insights` becomes a virtual attribute backed by
  a new `subQueryInsightCTAs` filter that joins child docs at read
  time. Consumers still get CTAs embedded on the insight response —
  one round-trip from their perspective.
- The CTA descriptor's within-insight identifier renamed `id` → `key`
  (clashed with the document `$id`). Validator updated.

Endpoints:
- Manager Create now persists CTAs as separate `ctas` documents after
  the parent insight, then re-fetches the insight so the response
  carries the freshly-joined CTA list.
- User Update trimmed to user-controlled state only (`severity`,
  `status`). `title`, `summary`, `payload`, `ctas`, and `analyzedAt`
  are analyzer-controlled — analyzers re-ingest by deleting and
  POSTing again to the manager endpoint.
- Insight Delete cascades to CTAs.
- Report Delete cascades through Insights → CTAs.

Response model:
- InsightCTA gains the standard document headers (`$id`,
  `$createdAt`, `$updatedAt`) and an `insightId` backref. The
  caller-supplied identifier is now `key`.

Tests:
- E2E sampleCTA factory uses `key` everywhere; testCreate asserts the
  freshly-created CTA carries `$id`, `$createdAt`, `insightId`, and
  the right shape.
- Dropped the testUpdate*CTA* tests — user Update no longer accepts
  CTAs. testDismissViaUpdate now depends on testUpdate directly.
- Unit tests rewritten to validate `key` instead of `id`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:07:49 +12:00
Jake BarnbyandClaude Opus 4.7 a1f64c6f71 refactor(insights): split CTA action into service + method
- InsightCTA model now exposes `service` (SDK namespace) and `method`
  (function name) instead of a single `action` string. Drops the
  string-splitting burden on every consumer and lets the console reach
  the right SDK method directly.

- Validator requires both `service` and `method` non-empty; same
  16-entry max still enforced.

- Endpoint normalization (Create + Update) splits the new shape into
  the persisted CTA descriptor.

- Constants split: INSIGHT_CTA_SERVICE_* (databases / tablesDB /
  documentsDB / vectorsDB) and INSIGHT_CTA_METHOD_* (createIndex).

- Insight model + InsightCTA model docs updated with the new field
  semantics and per-engine examples.

- E2E factory `sampleCTA($id, $engine)` emits the correct service and
  engine-appropriate params keys (tableId/columns for tablesDB;
  collectionId/attributes everywhere else). Engine matrix asserts
  `service` and `method` independently.

- Added e2e + unit coverage for the new failure modes (missing
  service, missing method, empty service, empty method).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 16:35:33 +12:00
Jake BarnbyandClaude Opus 4.7 8f79379b6e test(insights): full e2e + per-engine CTA action mapping
- Restructure InsightsBase trait with explicit helper methods
  (createInsight/getInsight/listInsights/updateInsight/deleteInsight,
  createReport/getReport/listReports/updateReport/deleteReport, plus
  sampleInsight/sampleCTA factories) — same shape ProxyBase uses.

- Add coverage for: report CRUD + duplicate-id rejection, invalid type
  rejection, list filtering by all allowed attributes, cursor
  pagination + missing-cursor, update preserving untouched fields,
  CTA validation edge cases (duplicate ids, empty fields, count > 16),
  dismissal round-trip + status filter, report cascade delete,
  unauthorized access (no server key), empty-result list.

- Engine-specific insight types (tablesDBIndex, documentsDBIndex,
  vectorsDBIndex, plus the legacy databaseIndex) so the CTA's `action`
  can map to the matching public API: databases.createIndex,
  tablesDB.createIndex, documentsDB.createIndex,
  vectorsDB.createIndex. dataProvider drives the engine matrix and
  asserts the right action lands in the persisted CTA. Constants for
  each action name live in app/init/constants.php.

- InsightCTA model docs spell out which action belongs to which engine
  and that the params keys differ between APIs (tableId/columns for
  tablesDB vs collectionId/attributes for the legacy / DocumentsDB /
  VectorsDB APIs).

- Insight model `type` description now lists every engine variant.

- CTAsTest gains coverage for object-shaped params, empty-action and
  empty-label rejection, and the default 16-entry cap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 16:25:49 +12:00
Jake BarnbyandClaude Opus 4.7 00565ea471 refactor(insights): metadata-only CTAs, platform DB, reports parent
Address review feedback on PR #12194:

- Pivot CTAs to pure descriptors (id/label/action/params). Drop the
  server-side execution layer: Action interface, registry, the
  databases.indexes.create CTA action, the params validator, the
  /v1/insights/:id/ctas/:id/executions endpoint, the InsightCTAExecution
  model, the INSIGHT_CTA_* errors, and the corresponding events. The
  console invokes the existing public API directly with the descriptor's
  action + params.

- Restore Databases\Indexes\Action.php to its pre-CTA shape and inline
  the index-create body back into Create.php (the createIndex helper
  was added solely for CTA reuse).

- Move insights collection from project DB to platform DB and add a
  parent reports collection alongside it. Insights carry projectId /
  projectInternalId for tenant scoping and an optional reportId for
  grouping. List endpoints filter by projectInternalId; Get/Update/
  Delete also enforce project ownership before touching the document.

- New Reports module with full CRUD (Create/Get/XList/Update/Delete),
  Report response model, Reports query validator, REPORT_NOT_FOUND /
  REPORT_ALREADY_EXISTS errors, reports.read / reports.write scopes,
  and reports.* event tree. Delete cascades to child insights.

- Update.php now mutates the loaded document via setAttribute (instead
  of passing a partial new Document), reuses CTAsValidator (instead of
  the looser ArrayList<JSON> + isset check), and rejects duplicate CTA
  ids.

- Create.php enforces unique CTA ids during normalization.

- CTAsValidator gained a configurable maxCount (default 16) so the
  Create path matches the Update path and the DB column size, and
  oversized payloads return a clean 400.

- Validator\Queries\Insights adds status and reportId to
  ALLOWED_ATTRIBUTES so dismissal / report workflows are filterable.

- Realtime channel parser guards $parts[1] for both insights and
  reports event names.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 13:46:07 +12:00
Matej Bačo 305e8e1ec7 Add request filter 2026-05-05 16:24:41 +02:00
ArnabChatterjee20k bca876acaf Merge remote-tracking branch 'origin/1.9.x' into big-int 2026-05-05 18:55:11 +05:30
Jake BarnbyandClaude Opus 4.7 69c637c72d style(insights): use aliased import for DatabasesIndexesCreate registry entry
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 15:01:31 +12:00
Jake BarnbyandClaude Opus 4.7 242c7f75ad refactor(insights): nest databases create-index CTA under resource path
Move the action class from Action/DatabasesCreateIndex.php to
Action/Databases/Indexes/Create.php so the directory mirrors the
underlying resource hierarchy. Action name follows: databases.createIndex
becomes databases.indexes.create, with the constant renamed to
INSIGHT_CTA_ACTION_DATABASES_INDEXES_CREATE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:57:28 +12:00
Jake BarnbyandClaude Opus 4.7 f779c7aa3b refactor(insights): collapse dismissal into a status field on update
Dismissal was a sub-resource (POST /v1/insights/:id/dismissals) but a
dismissal is just a state transition, not a thing the client creates.
Drop the dedicated endpoint and add a `status` enum (`active` |
`dismissed`) to the insights schema, settable via the existing PATCH
update route. The server still derives `dismissedAt` and `dismissedBy`
on transition for audit/sorting, but the client-facing API is just a
single status toggle.

- Schema: add `status` attribute (default `active`)
- Constants: add `INSIGHT_STATUSES`
- Update endpoint: accept `status` param, derive dismissedAt/By on
  active <-> dismissed transitions
- Response model: add `status` rule
- Drop Insights/Dismissal/Create.php, the createInsightDismissal SDK
  method, the `insights.[id].dismissals.create` event, and the
  `insight.dismissal.create` audit
- E2E: replace testCreateDismissal with testDismissViaUpdate covering
  both directions of the toggle

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:36:31 +12:00
Jake BarnbyandClaude Opus 4.7 cd539d972a refactor(insights): capitalise CTA acronym in identifiers
Project-specific override of the default camelCase-acronyms convention:
namespaces, class names, file paths, and SDK method names use `CTA` in
all caps. Touches all insights surfaces — directories, response models,
validators, container resource keys, and SDK method names like
`createInsightCTAExecution`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:27:45 +12:00
Jake BarnbyandClaude Opus 4.7 d188bd7a2e refactor(insights): register CTA registry on the global $register
Persist the insight CTA registry across requests by attaching it to the
boot-time global $register, mirroring the pattern used for `geodb`,
`passwordsDictionary`, `hooks`, etc. The container resource now looks
the registry up from `$register` instead of rebuilding it on every
request.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 14:22:10 +12:00
Jake Barnby da5a137b98 refactor(insights): nest CTA execution and dismissal as sub-resources
Move POST /v1/insights/:id/dismiss to /v1/insights/:id/dismissals
and POST /v1/insights/:id/ctas/:ctaId/trigger to
/v1/insights/:id/ctas/:ctaId/executions, with the corresponding
class moves into Http/Insights/Dismissal/Create.php and
Http/CTA/Execution/Create.php. Rename the response model to
InsightCtaExecution and update events.php to surface dismissal
and execution as resource events with create verbs. The reshape
matches the rest of the API where verbs hang off plural sub-resources.
2026-05-01 14:04:31 +12:00
Jake Barnby f5d6f6e27c refactor(insights): use Utopia Platform Action and Registry
Replace the bespoke CtaAction/Registry with Utopia\Platform\Action
and Utopia\Registry\Registry. Implement DatabasesCreateIndex with
the full createDocument('indexes') + queue path used by the existing
indexes endpoint, validated via a dedicated Utopia validator. Drop
the obsolete unit tests (custom-Action contract) in favor of
validator-focused tests.
2026-05-01 13:40:27 +12:00
Jake BarnbyandClaude Opus 4.7 e1ddcd051c feat(insights): add schema, scopes, events, errors, constants
Wires the platform glue for insights: the `insights` collection on the
project database, the `insights.read` / `insights.write` scopes, the
`insights.[insightId]` event tree (including the nested `ctas.[ctaId].trigger`
event), the typed exceptions, and the runtime CTA registry resource.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 12:40:28 +12:00
ArnabChatterjee20k 88bbb965f8 Merge remote-tracking branch 'origin/1.9.x' into presence-api 2026-04-30 16:41:48 +05:30
ArnabChatterjee20k 869c35416d Refactor presence API to standardize scope and attribute names. Updated 'presence' to 'presences' across roles, scopes, and HTTP methods for consistency. Renamed 'expiry' to 'expiresAt' in various locations to improve clarity and maintainability. 2026-04-30 13:30:15 +05:30
fogelito d98bd8c972 Remove line 2026-04-30 10:44:21 +03:00
fogelito c0bba74eee set setGlobalCollections logs 2026-04-30 10:36:12 +03:00
fogelito f03cc847f8 Merge branch '1.9.x' of https://github.com/appwrite/appwrite into set-global-collection
# Conflicts:
#	composer.lock
2026-04-29 17:07:32 +03:00
fogelito 8eed06678b formatting 2026-04-29 15:54:05 +03:00
fogelito 7a9a2899ff setGlobalCollections 2026-04-29 15:41:56 +03:00
Torsten Dittmann dfbf45f4cc Merge branch '1.9.x' into feat-out-of-order-chunk-uploads 2026-04-29 15:03:33 +04:00
ArnabChatterjee20k 06a05311a4 Merge remote-tracking branch 'origin/1.9.x' into presence-api 2026-04-29 15:04:20 +05:30
Matej Bačo e75fc5b859 Add list scopes endpoint for Console 2026-04-29 10:08:31 +02:00
ArnabChatterjee20k b08f3bdc52 Merge remote-tracking branch 'origin/1.9.x' into presence-api 2026-04-29 11:29:59 +05:30
Matej Bačo c1f61b22aa Merge branch '1.9.x' into feat-create-dynamic-keys 2026-04-28 17:18:36 +02:00
Matej Bačo 980762fc3e Rename from dynamic key to ephemeral key (api keys) 2026-04-28 17:18:06 +02:00
Matej Bačo b2ce95a0cd Dynamic key backwards compatibility 2026-04-28 16:14:10 +02:00
Harsh Mahajan 67d24d3ef1 Merge branch '1.9.x' into feat/impersonation-query-params 2026-04-28 19:11:14 +05:30
harsh mahajan 87ed7c3817 feat: add query param fallback for all impersonation params and simplify tests 2026-04-28 19:10:55 +05:30
Torsten Dittmann a0ef145b92 Merge branch '1.9.x' of https://github.com/appwrite/appwrite into feat-out-of-order-chunk-uploads 2026-04-28 17:10:56 +04:00
ArnabChatterjee20k 8d378720b0 add presence API metrics and usage tracking 2026-04-28 17:19:24 +05:30
Matej Bačo cb4cff120b Add Keycloak oauth support 2026-04-28 10:54:13 +02:00
Matej Bačo 49e6a38e7f Add fusionauth oauth 2026-04-28 10:43:16 +02:00