Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 4.8 3fa781004d feat(roles): add bond integration-importance factor to shared services
`bond` is a 0..1 factor for how strongly a service is tied to the overall
integration: bond: 1 = always required, bond: 0 = omittable. Groundwork for
tooling that later scores service importance and decides what can be dropped.
Named `bond` (not `bound`) to avoid clashing with the resource bounds/limits.

Add test_service_bond.py (lint): every enabled + shared service must declare a
valid `bond` (number in 0..1). Seed `bond: 1` as a placeholder on all 638
enabled+shared service entries across 88 roles, to be refined later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:17 +02:00
kevinveenbirkenbachandClaude Opus 4.8 50fe3bf623 feat(roles): declare compose resource limits for self-run services
Extend test_compose_resource_limits.py to enforce resource limits on every
container a role runs itself (not provided by another role via the service
registry): the primary entity needs min_storage/cpus/mem_reservation/mem_limit/
pids_limit; uncovered sidecar containers need the four resource keys. A service
is exempt only when another role covers it (e.g. discourse's postgres ->
svc-db-postgres, whose entity declares the limits), replacing the previous
blanket shared:True skip.

Declare the previously-missing limits across 18 roles: mostly self-run redis
cache sidecars (cpus "0.5" / 128m / 512m / 512), plus the minio mc client,
the coturn gateway, and the web-svc-* css/html/asset/cdn/file provider entities.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 a71cf55844 style(web-app-nextcloud): autoformat-wrap integration_openai configvalue
mbake line-wrap of the long configvalue jinja expression. Cosmetic only;
the rendered value is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 1a1a02a2d6 fix(web-app-nextcloud): drop dead popup reference in openproject spec
Leftover 'if (popup) await popup.close()' referenced a variable removed
together with the connect-button/popup OAuth flow -> eslint no-undef ->
lint-javascript red -> make test red. make test is green again. No change
to the spec's assertions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 01f0b8686a fix(web-app-nextcloud): assert openproject admin OAuth coupling, not a connect button
OpenProject's integration_openproject renders no 'Connect to OpenProject'
button on connected-accounts (unlike discourse/gitlab/mattermost); the
connection happens via the Files smart-picker / the OpenProject side. The
spec's connect-button + OAuth-authorize popup flow tested non-existent UI.

Assert the real provisioned bidirectional coupling instead, read from the
admin initial-state config: openproject_instance_url (partner host),
openproject_client_id, openproject_client_secret, authorization_method=oauth2.

NOTE: NOT yet verified green live -- the compose-playwright verify run was
OOM-killed (exit 137) before finishing. High confidence by logic only: in the
prior run this spec already passed the instance-URL check (same JSON.parse
path), failing only on the now-removed connect-button assertion, and all
asserted fields are confirmed present in the decoded admin config. Re-run a
scoped verify to confirm before relying on it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ed4b061408 fix(web-app-nextcloud): store integration OAuth creds Nextcloud-encrypted
integration_gitlab/integration_mattermost read client_id/client_secret via
crypto->decrypt(appConfig->getValueString(lazy:true)). Provisioning set them
with 'config:app:set --sensitive', the wrong scheme -> "Authenticated
ciphertext could not be decoded" -> the connected-accounts admin page 500s,
cascading onto the discourse/matrix/mattermost addon specs.

Add set_encrypted_appconfig.php (crypto->encrypt + appConfig setValueString
lazy -- the exact scheme the apps' setEncryptedAppValue uses) and route both
provisioning hooks through it. Verified live: gitlab client_id is now an
encrypted blob and connected-accounts renders again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6fea999e93 fix(tests): make make test green (eslint + env order + autoformat)
- discourse-activity-pub, integration_matrix specs: drop unused catch
  binding and useless json init (eslint no-unused-vars/no-useless-assignment)
- openwebui playwright.env.j2: order OLLAMA_SERVICE_ENABLED after
  OIDC_ISSUER_URL (env keys must be ASC, test_alphabetical_sort)
- test_addon_env_flags.py: autoformat

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 d5ef4c1327 fix(web-app-nextcloud): correct addon spec selectors against live DOM
The drawio/files_bpm/external/fileslibreofficeedit/whiteboard addon specs
asserted guessed routes/selectors that do not exist on the live stack.
Verified against the running Nextcloud (make compose-playwright):
- drawio, fileslibreofficeedit: no standalone app route -> assert the app
  is registered+enabled in OC.appswebroots (Files file-action apps)
- files_bpm: modeler surface is #bpmn-app, not #canvas.bpmn-canvas
- external: admin section is #external + #add_external_site
- whiteboard: backend URL is injected in #initial-state-whiteboard-url

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:16 +02:00
kevinveenbirkenbachandClaude Opus 4.8 06aa25c095 feat(ai): integrate OpenWebUI/Ollama as a real integration_openai backend + chat test
- svc-ai-ollama variant-0: preload smollm2:135m (smallest instruct model for CI)
- integration_openai meta: Service URL -> {base}/api for the OpenWebUI backend
- web-app-openwebui: enable_api_keys config flag (services.yml + vars) rendered into
  ENABLE_API_KEYS so sk- API keys authenticate against the OpenAI-compatible API
- integration_openai spec: drop the DOM-gated skip, assert the partner backend host
  (openwebui chat.ai / flowise flow.ai), distinct from Nextcloud
- openwebui: OLLAMA_SERVICE_ENABLED playwright flag + test-ollama-chat.js asserting
  the preloaded model answers a chat completion over OpenWebUI -> Ollama

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 51fbe1a52a test(web-app-wordpress): wp-discourse spec asserts the WordPress->Discourse partner coupling
Replace the settings-page check with the real bridge: the wp-discourse connection
tab carries the partner Discourse base URL (distinct host), and the provisioned
Discourse API credentials authenticate against the partner instance
(/session/current.json resolves the publishing user on the Discourse host).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 dbb4f5f96f test(web-app-wordpress): infinito-oidc-rbac-mapper spec asserts the OIDC bridge to Keycloak
Replace the users-list-renders check with the real cross-partner bridge: wp-login
redirects to the Keycloak partner authorize endpoint (distinct host) with
response_type=code, the provisioned client_id and a scope carrying the groups claim
the RBAC mapper consumes, then lands on the wp-admin role-mapping surface.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c01c9331db test(web-app-wordpress): activitypub spec asserts WordPress is a discoverable Fediverse actor
Replace the wp-admin settings-page check with a real federation probe: WebFinger
resolves the author acct to a rel=self ActivityStreams actor, which is fetched and
asserted to carry the AS @context, an actor type, id, inbox/outbox on this host, and
an RSA publicKey — the surface remote Fediverse partners federate with.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 eeb7f0cc15 test(web-app-odoo): stock spec asserts the Inventory module + operations action
Replace the generic surface check with the Inventory app identity, no invalid-action
error, the stock.picking operations dashboard, and stock-specific operation types
(Receipts/Deliveries/Internal Transfers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 17fa250e24 test(web-app-odoo): sale_management spec asserts the Sales module + quotations action
Replace the generic surface check with the Sales app identity (breadcrumb/title),
the sale.order quotations list/kanban action, and the New create button.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 14a3a1a6d2 test(web-app-odoo): crm spec asserts the CRM module is installed and its pipeline renders
Replace the generic surface check with no-error-page + the CRM control panel and a
CRM-specific surface (lead/opportunity kanban, New, Pipeline) plus CRM domain
vocabulary, proving the crm module loaded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 319e86fc07 test(web-app-odoo): account spec asserts the Accounting module is installed
Replace the generic web-client surface check with module-specific signals: no Odoo
error dialog, the Accounting/Invoicing app brand in the navbar, and an
account-specific top menu (Customers/Vendors/Chart of Accounts).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 dec65ae175 test(web-app-nextcloud): xwiki spec asserts the admin instances table + partner coupling
Drop the DOM-gated skip; assert the xwiki admin instances table renders (route not
404), no 'no wikis registered' placeholder, and a configured instance-url input
whose host is the XWiki partner, not Nextcloud.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 59ee61ddfa test(web-app-nextcloud): whiteboard spec asserts the admin settings + collab backend URL
Replace the generic Files-app check with the app's own settings/admin/whiteboard
section and assert the collab-backend URL field is present and non-blank, proving
the plugin_configuration reached the running app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9a23ef4bd2 test(web-app-nextcloud): spreed spec keeps the deterministic HPB partner coupling
Keep the deterministic config coupling (OCS spreed signaling capability + the Talk
admin TURN server pinned to the web-svc-coturn partner host, STUN server, signaling
host) with a best-effort live 'Test this server' check; drop the comment blocks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cf19e242c5 test(web-app-nextcloud): richdocuments spec asserts the Collabora WOPI partner coupling
Assert the admin section renders, the wopi_url field carries a real partner URL
whose host is distinct from Nextcloud, and the Collabora connection-failure banner
stays absent, proving the connector reached the partner WOPI server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 dd1e42f065 test(web-app-nextcloud): recognize spec asserts its admin settings UI mounts
Assert the recognize admin Vue component (#recognize) and its own Face-recognition
section render, not the generic settings shell.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2d9bc895ed test(web-app-nextcloud): onlyoffice spec asserts a document opens in the partner editor
Replace the config-presence check with a real round trip: upload a valid .docx,
open it, and assert the ONLYOFFICE editor iframe is served by the web-svc-onlyoffice
partner host, shows no JWT/download error, and renders its editor surface.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:14 +02:00
kevinveenbirkenbachandClaude Opus 4.8 396968016d test(web-app-nextcloud): metadata spec asserts the metadata provider bundle is loaded
Assert the metadata app is registered in OC.appswebroots and its own frontend
bundle (apps/metadata/...) is injected into the Files page, proving the provider is
loaded and coupled, not just listed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 88f8eb08d8 test(web-app-nextcloud): integration_zammad spec asserts the real Zammad OAuth coupling
Drop the best-effort early-return; assert the admin instance URL is the partner
(not Nextcloud) and the per-user connect drives the partner /oauth/authorize with
the provisioned client_id + response_type=code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 7597888a22 test(web-app-nextcloud): integration_peertube spec asserts the real PeerTube OAuth coupling
Drop the DOM-gated skip; assert the admin panel exposes the provisioned partner
instances list (distinct from Nextcloud) and the per-user connect drives the OAuth
authorize on the partner instance with the provisioned client_id + response_type=code.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c83d700afc test(web-app-nextcloud): groupfolders spec asserts the admin app mounts
Assert the groupfolders admin Vue app (#groupfolders-wrapper/#groupfolders-root)
mounts, not the generic settings shell, proving the app is installed and enabled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 7608f94e5f test(web-app-nextcloud): fileslibreofficeedit spec asserts its admin settings section renders
Target the app's own settings/admin/fileslibreofficeedit route (not 404) and assert
its LibreOffice editor admin panel and document-editor server URL field render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 67398cff8d test(web-app-nextcloud): files_linkeditor spec asserts its New-link menu entries register
Open the Files New menu and assert the 'New link (.URL)' and 'New link (.webloc)'
entries the app injects are present, proving its frontend bundle loaded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9d6ec1ccf9 test(web-app-nextcloud): files_bpm addon spec asserts the BPMN modeler canvas renders
Target the app's own apps/files_bpm/ route (not the generic Files app) and assert
it resolves (not 404) and the #canvas.bpmn-canvas modeler surface renders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 a345d7a482 test(web-app-nextcloud): external addon spec asserts the External-sites admin panel renders
Target the app's own settings/admin/external section and assert its description
text and 'New site' action render, proving the external app's section and template
are served by the enabled app (not the generic additional-settings shell).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9d787ff03b test(web-app-nextcloud): event_update_notification spec asserts it is an enabled app
The app is backend-only (no user route); assert via the Provisioning OCS registry
that event_update_notification is in the enabled-apps list and not in the disabled
list, so a disabled/absent app fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 1f474d070e test(web-app-nextcloud): epubviewer addon spec asserts the reader panel + persisted config
Drop the DOM-gated skips; assert the settings/user/epubviewer section resolves
(not 404), the #reader-personal panel renders, and the #EpubEnable checkbox
reflects the persisted user config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b33a8ff85e test(web-app-nextcloud): drawio addon spec asserts the drawio editor surface renders
Drop the DOM-gated skips; assert the apps/drawio/ route resolves (not 404) and the
drawio-specific editor surface mounts, so a disabled/broken app fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 5fcfdc7577 test(web-app-nextcloud): bbb addon spec asserts the cloud_bbb app UI renders and is coupled
Navigate to apps/bbb/ and assert the cloud_bbb app shell + its own room-management
surface render, in addition to the admin api.url/api.secret partner coupling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ce74174512 test(web-app-matrix): mautrix-whatsapp spec asserts the bridge bot is provisioned on Synapse
Drop the skip stub; resolve the @whatsappbot appservice profile against the partner
Synapse host and assert it returns 200 with a WhatsApp-branded display name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 837b315f75 test(web-app-matrix): mautrix-telegram spec asserts the bridge bot is provisioned on Synapse
Drop the skip stub; assert the @telegrambot appservice profile resolves on Synapse
(200, not 404/5xx) and returns the bridge bot profile object.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 40d8af80ed test(web-app-matrix): mautrix-slack spec asserts the bridge bot is provisioned on Synapse
Drop the skip stub; assert the @slackbot appservice profile resolves on Synapse
(200, not 404/5xx) with a Slack-branded display name.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cdef114add test(web-app-matrix): mautrix-signal spec asserts the bridge bot is provisioned on Synapse
Drop the skip stub; assert the @signalbot appservice profile resolves on Synapse
with a Signal-branded display name, plus a negative control (unregistered bot 404).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 020b5a0cf6 test(web-app-matrix): mautrix-instagram spec asserts the bridge bot is provisioned on Synapse
Drop the skip stub; probe Synapse for the @instagrambot appservice bot (must
resolve, not 404/5xx) and add a negative control (an un-bridged localpart must 404)
so the probe really exercises the bridge appservice namespace.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 95e783d6b4 test(web-app-matrix): mautrix-facebook spec asserts the bridge bot is provisioned on Synapse
Drop the unconditional skip stub; probe the partner Synapse homeserver for the
@facebookbot appservice bot profile and assert it resolves (HTTP 200), proving the
bridge registered its appservice and the round-trip to Synapse succeeded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4d00faa77b test(web-app-discourse): docker_manager spec asserts the plugin is installed, enabled and serving its upgrade surface
Drop the DOM-gated skip; assert docker_manager is present and enabled in
/admin/plugins.json and the /admin/upgrade.json surface it owns is served.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b9ab644ab0 test(web-app-discourse): discourse-ldap-auth spec asserts real LDAP partner directory binding
Drop the existence-only checks; assert ldap_auth/sync enabled, ldap_sync_host is a
distinct partner host (not Discourse itself), a numeric bind port, ldap_base_dn is a
real directory root, and ldap_bind_dn is rooted in the same partner tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 eece84af91 test(web-app-discourse): discourse-akismet spec asserts real Akismet partner coupling
Drop the DOM-gated skip; assert akismet_enabled is active, anti_spam_service is
akismet, and akismet_api_key is provisioned so Discourse can authenticate against
the Akismet partner API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ce247c0f2f test(web-app-discourse): discourse-activity-pub spec asserts real ActivityPub federation
Drop the DOM-gated skip; assert activity_pub_enabled is active, the WebFinger
actor-discovery endpoint is live, the /ap federation surface serves JSON, and
remote-handle validation resolves a fediverse partner host distinct from the
Discourse host (real cross-host federation, not a local echo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c9a431e298 fix(web-app-nextcloud): make integration_openproject NC OAuth2 client step best-effort
Push the OpenProject OAuth credentials (authorization_method, openproject_client_id,
openproject_client_secret) into Nextcloud before the NC OAuth2 client step so the
forward connect is always provisioned. The reverse-direction Nextcloud OAuth2 client
relies on occ oauth2:add-client, which Nextcloud 33 does not ship, so it is now
failed_when: false with its dependents in a guarded block — the deploy completes
instead of aborting before the Playwright suite runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 1d6bc786ff refactor(web-app-nextcloud): drop redundant | default('') on always-set register stdouts
The integration_openproject / integration_gitlab provisioning and the user_ldap
config probe read their state with tasks that always run (no when:) and
failed_when: false, so their .stdout is always defined; 'X.stdout | default('') |
trim' is identical to 'X.stdout | trim'. Remove the dead default('').

Genuinely-guarding defaults are kept: the s01 config-id fallback, the skippable
ldap auto-create stdout/stderr, the regex_search None guards, and the outer
default(..., true) fresh-or-persisted secret fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 38796b77a5 fix(web-app-nextcloud): recover integration_openproject OAuth secret on re-deploy
OpenProject only returns a fresh OAuth client secret when the application is first
created; on a re-deploy where the app already exists but Nextcloud never persisted
the secret (e.g. an earlier deploy failed downstream at the storage step), the
secret is unrecoverable and the provisioning assert tripped, aborting the play
before the Playwright suite ran.

ensure_nextcloud_storage.rb now destroys and recreates the OAuth application when
it exists but Nextcloud holds no secret (gated to the first call via the absent NC
client id), so a fresh secret is always emitted. The provision task passes the
persisted-secret read as NC_HAS_OP_SECRET only on that first call so the second
(client-register) call never destroys the freshly created app. Verified
in-container: the recovery path emits a fresh openproject_client_secret.

Also drops the redundant | default('') on the always-set
nextcloud_op_client_secret_current.stdout in this file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 1496174e29 test(web-app-nextcloud): real integration_moodle token round-trip coupling
Drive the real bridge: pin the per-user #moodle-url to the deployed partner
Moodle host (distinct from Nextcloud), persist it, then Connect and assert the
POST /apps/integration_moodle/get-token response is a genuine partner verdict
(200 with user_name minted by the partner webservice, or 401 partner-refused) —
proving the request reached the partner Moodle, not a local stub. bridges:
[moodle] means the deployment gate skips it when the partner is not deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2a8e11462c test(web-app-nextcloud): real integration_mattermost OAuth coupling
Assert the admin oauth_instance_url points at the partner Mattermost host (not
Nextcloud) and the admin panel exposes the provisioned OAuth client, and the
per-user connect drives an OAuth authorize redirect to that partner host with
the provisioned client_id + response_type=code. Backed by the
integration_mattermost_provision hook; bridges: [mattermost] with the partner in
the deploy set means this runs live and fails if provisioning or the connect is
broken.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2c39e18478 test(web-app-nextcloud): real integration_matrix homeserver coupling
Drop the DOM-gated skip; assert the admin Matrix panel renders, the configured
homeserver is the deployed partner (distinct from Nextcloud), and the per-user
connect drives a real session against the partner homeserver (a browser
/_matrix/client/ call to the partner, or the nextcloud integration_matrix
connect round-trip). bridges: [matrix] with the partner in the deploy set means
this runs live and fails on a broken coupling instead of skipping on the DOM.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 06:03:10 +02:00