Skip to content

feat: introduce the Communications Nextcloud application (POC) - #1

Merged
vitormattos merged 121 commits into
mainfrom
feat/initial-communications-app
Nov 15, 2026
Merged

vitormattos merged 121 commits into
mainfrom
feat/initial-communications-app

Conversation

@vitormattos

@vitormattos vitormattos commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Purpose

Introduce Communications (communications) as a Nextcloud 36 development app extracted from the unpublished OCB Rio proof of concept. Institutional publications can use contextual banners/modals, separate Inbox, Notifications, Activity, email, optional Two-Factor Gateway channels, and generic Nextcloud app events. There is no LibreSign-specific runtime adapter.

Status: draft. No merge, production deployment, app-store release or migration from the older contextualcampaigns POC is authorized.

Architecture and standards

  • Routes: 36 controller attributes (#[FrontpageRoute]); route/schema contract checked in disposable Nextcloud tests. A single initial migration replaces the historical development migration chain.
  • Persistence: delivery and lease SQL live in DeliveryMapper (QBMapper), not the delivery orchestration service.
  • Frontend: Vue 3 and strict TypeScript, plus Nextcloud Nc* UI components. All 10 Vue SFCs now use the official @nextcloud/prettier-config (4-column tabs across template, script and scoped style). npm run lint includes the formatting check to prevent regressions; format:vue:fix applies the upstream formatter. @nextcloud/axios/@nextcloud/router replace repeated native HTTP calls; fetch(keepalive) remains only for unload-time acknowledgements. Campaign input conversion, serialization and validation are isolated in a typed, unit-tested service.
  • Styles: the Nextcloud Vue design system and theme variables are authoritative. Local styles live in scoped SFCs; residual src/management.css has 13 lines for the app mount. Removed 91 rules with no source references. Some component-local CSS remains for custom layouts and should continue to be reviewed, not copied into a global framework.
  • Icon: monochrome img/app.svg and theme-appropriate app-dark.svg, no fixed LibreCode green.
  • Licensing: six redundant .patch.license sidecars removed; one REUSE.toml annotation covers the remaining patch, and REUSE 3.3 reports 159/159 annotated files.
  • Internationalization: English source messages, Portuguese fallback catalogs, .l10nignore and official .tx/config prepare for Nextcloud Transifex onboarding. Automatic translations are not yet activated; this requires project registration and bot permissions. Do not remove fallback catalogs prematurely.
  • TypeScript formatting: @nextcloud/prettier-config now checks all 21 tracked TS files through the normal npm run lint workflow. An upstream @nextcloud/eslint-config@9.0.1 diagnostic was performed and removed after analysis: 232 remaining errors and 138 warnings even after automatic fixes, primarily in the monolithic Vue editor. Full adoption of that stronger Nextcloud lint preset is not claimed and needs its own behavioral-preserving frontend refactor rather than disabling rules.
  • Documentation: All five docs/*.md guides are now in English. The API guide documents the actual communications endpoints, delivery and gateway guides drop obsolete POC claims, and TESTING.md records the shared-catalog state, matrix, sharding and lossless-report acceptance contract.
  • PHP design: publication input normalization was moved from persistence into CampaignInputValidator; DeliveryFrequencyPolicy, GuestBannerPolicy, and CampaignOrderPlanner isolate business rules with parameterized unit tests. TriggerCatalog separates built-in/native/registered capability discovery; DeliveryStore separates browser event preparation. Invalid reordering now uses typed CampaignOrderException, with user-facing translations at the repository boundary. PHP uses Nextcloud\\CodingStandard\\Config and an additional CI check for malformed continuation indentation and overlong PHPDoc; transactional rollback and optional integration isolation retain deliberate \\Throwable catches.
  • PHP persistence and error boundaries: Application registration is split into bootstrap listener setup, and Command/PublishDue delegates bounded work to PublicationDrainer and a shared PublicationDuePolicy. The public webhook delegates HMAC checking to WebhookSignatureVerifier and catches typed validation/storage exceptions. Database queries for events, outbound publication attempts, Inbox/comments, campaigns and native subscriptions now live in lib/Db/{EventMapper,BoardPublicationMapper,BoardMapper,CampaignMapper}; services/controllers enforce policy and authorization without direct SQL. Campaign reorder and archive deletion remain atomic with rollback-on-Throwable inside the mapper and a typed conflict error. Optional third-party gateways, native listeners and uncertain SMTP handoffs retain deliberate exception isolation; do not change their retry semantics without transport-level tests.
  • Frontend distribution: Source-only Git layout: src/ owns the two lightweight Nextcloud adapters and guest styles alongside Vue/TypeScript; js/ and css/ are entirely generated and gitignored. A clean build removes stale assets. npm run package:app creates an unsigned communications/-rooted archive with five JS and four CSS runtime files, and excludes development source, test and tooling directories. npm run test:package exercises missing/empty assets, stale cleanup and archive contents. The separate GitHub Verify installable application package CI uploads a review-only test package, not an App Store release.
  • Workflow reuse: lint/build/REUSE, Node, PHPStan, PHPUnit (SQLite/MariaDB/PostgreSQL) and Playwright are synchronized from a single catalog, LibreCodeCoop/.github, with one .github/actions-lock.txt. Merged organization PR #115 pins Nextcloud sources and normalizes runner labels. Communications keeps one small playwright.yml.patch (41 lines, previously 67): its SQLite 2-shard / PostgreSQL / MariaDB matrix and invocation of the local scripts/ci/run-playwright.sh wrapper. The wrapper provisions the test-only environment, asserts route/schema contracts and cleans up even on failure. Native Playwright database tags and blob reporting prevent silent artifact overwrites during report merging. The catalog synchronizer preserves the last valid workflow when a patch fails. Frontend/backend mutation jobs are application-specific.

Evidence on current revision

  • Backend verification: the previous revision 87671e2 completed 18 of 19 workflows successfully (including PHP-CS-Fixer, PHPStan, all three PHPUnit database suites and build checks), with Playwright still pending. Further mapper extraction on 60fa8fdc triggered one PHP-CS import-order finding, fixed in d3bb6fe. The current HEAD requires its own complete CI and report-merge review; these are not certified by the earlier partial results.
  • Earlier local isolated Nextcloud 36-dev with LibreSign: 2/2 Playwright passed on a previous code revision, including audience isolation and the generic completion-event routing contract; it does not validate the current PHP refactors or final blob report merge.
  • Stryker frontend URL sanitizer: 73/78 mutants eliminated (93.59%), gated at 85%. Infection PHP URL sanitizer: 40/41 mutants eliminated (~97%), gated at 90%. Neither percentage measures the entire codebase.
  • CI on current head: GitHub Actions execution was unblocked after this repository was made public. The current head is d3bb6fe; rerun the full 19-workflow matrix, including PHPUnit SQLite/PostgreSQL/MariaDB and four Playwright database/shard jobs. The merge report must include all expected results. A green report-merge job alone is insufficient proof of completeness. This draft should not be merged without green checks and independent review.
  • Commits have verified cryptographic signatures and matching DCO; project REUSE licensing verified.

Catalog dependency status and known limitations

  • Shared catalog dependency resolved: LibreCodeCoop/.github#115 is merged; all 15 workflow lock entries reference b2013e8. Full current-head CI, Playwright merged-report evidence, and independent code review remain prerequisites before this draft can be marked ready or merged.

  • Unit coverage: PHPUnit exercises only a small proportion of backend lines (~1.07% in the prior full-codebase PCOV measurement). Integration and Playwright provide additional confidence but do not justify claiming full unit coverage. Authorization, delivery leases, concurrency and persistence would benefit from further focused unit/contract tests.

  • Complexity: current ESLint complexity audit warns at 15 for eight functions, including pure campaign conversion/validation; legacy monolithic editor code still warrants additional decomposition. Warnings are nonblocking during this prototype stage.

  • LibreSign: current scenario uses the real event class and synthetic event emission. It does not perform an external signature, request issuance or signed-PDF verification.

  • Transifex: native configuration is present, but Nextcloud-community resource onboarding and bot sync have not been performed; catalog files are retained until this is operational.

  • Compatibility/security: development Nextcloud 36 is not stable-release production certification; moderate transitive npm advisories remain in Nextcloud dependencies. No real outbound messaging provider, customer data, production Nextcloud account or live third-party gateway was used in this validation.

Independent code review remains required. Leave this PR in draft; do not merge it automatically.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ud mapper

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ript

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…tors

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…an Portuguese

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
… mutation gate

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ow provenance

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Move Vitest tests to tests/js/unit while keeping PHP unit tests
under tests/php/Unit and browser tests under tests/e2e. Update the
TypeScript project and Vitest discovery globs and preserve relative
imports. Avoid a central inventory of individual test files.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Extract application selection, page-route filtering and Flow/webhook
configuration into focused Vue components with typed props and events.
Keep the host trigger state machine responsible for switching modes,
and use one documented TRANSLATORS context per translated string.
Add a browser regression for route-capable applications and advanced
integration setup in a disposable Nextcloud environment.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Delete obsolete script copies after moving the disposable Nextcloud
runner to tests/ci. Discover FrontpageRoute and ApiRoute declarations
from the controller attributes without maintaining a route inventory.
When the shared Nextcloud PHPUnit workflow removes Composer OCP stubs,
load IL10N from Nextcloud core instead; retain the Composer fallback
for standalone local unit tests. Reproduced with the stub masked.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Keep ignored paths and file globs on separate lines for easier
maintenance and cleaner future diffs. No lint rules or matching
patterns are changed.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
PostgreSQL introspection names primary indexes oc_*_pkey and
MariaDB exposes PRIMARY while SQLite uses primary. Keep verifying
primary key columns, uniqueness and all named secondary indexes,
without treating a database-generated primary index name as a
schema regression. Verified on disposable PostgreSQL and MariaDB
Nextcloud 36 installations and against the PHP test suite.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Replace tightly packed multilingual Vue template expressions with
named, documented translations for independently extractable strings.
Use full sentences with named parameters for statistics, provider
counts, and archive confirmation; remove untranslated hardcoded
Portuguese and keep the pt_BR catalogs in sync. Checked the Vue
compiler, type checking, linting, 102 Vitest cases and production build.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Adopt LibreSign's bamarni/composer-bin-plugin pattern, with
independent locked environments for PHPUnit, PHPStan, Nextcloud
coding standard and Infection. Keep shared OCP and Symfony
development types in the root Composer vendor. Preserve no-dev
runtime installs and adapt mutation CI for post-install hooks.
Verified 165 PHP tests, PHP-CS-Fixer, PHPStan and Composer install.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Make PHPUnit suites and source inclusions independently editable
using multiline indented XML. Mark the XML and .gitignore with native
SPDX comments and remove redundant REUSE annotations. Annotate
isolated tool manifests and locks via the REUSE catalog. Verified
the XML via PHPUnit and all 233 tracked source files with REUSE 3.3.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Put the available capabilities, source-code freedom and no-fee
license terms first. Describe optional LibreCode Coop implementation,
maintenance, integrations, customization, and organizational support
without implying a paid-only edition. Explain how business support
and community contributions sustain the project, retain development
status warnings, and document isolated Composer toolchains.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Use the installed @nextcloud/prettier-config (tabs, visual width 4)
for all MJS source and browser tests, checked by the existing npm lint
command. Keep ESLint glob arrays multiline for maintainable diffs.
Remove unused hardcoded appVersion from all three Vite bundles; the
app manifest remains the authoritative release version.
Validated prettier, ESLint, TypeScript, Vitest and application build.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Audit all 13 Vue components and group 168 related selectors in
10 stylesheets using native Sass nesting. Preserve scoped style
semantics, avoiding arbitrary wrapping of teleported Nextcloud
dropdown elements. Compare the compiled CSS declarations,
selectors and order before and after; no generated rule changes.
Verify Nextcloud Prettier, Stylelint, TypeScript, Vitest, and build.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Separate campaign validation, hydration, banner color and CTA URL
policies into focused pure functions. Derive channel availability,
selected state and messages through testable domain helpers instead
of complex Vue computed callbacks. Extract public banner URL checks
and Nextcloud claim/activation/retry steps from browser adapters.
Add input/output tests for channel view models, safe public links,
and first-visit/CSRF-retry behavior with no internal call mocks.
Escalate ESLint complexity >15 from warning to error.
Verified 108 Vitest cases, TypeScript, lint, Stylelint, builds and
installable package checks.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Move the preview and six publication summary fields out of the
administration monolith into a focused presentation component with
explicit typed inputs and a preview event. Move its scoped SCSS and
translations with it; keep the editor as sole state owner. Avoid
hidden global state or internal-method mocks.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ients

Keep the extracted sidebar's Prettier-compatible template nesting
and resolve its final recipient label locally, rather than relying
on a parent-script variable.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
The extracted sidebar accidentally retained content following an
inner named-slot closing tag. Restore a single balanced component
template; the Vue compiler and lint will validate this regression.

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ntext

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…definitions

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ndor-bin

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…uild

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…mpaign editor

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
… for developers

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…agement state

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…omponents

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…oped to app mount

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
…ries

Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
@vitormattos
vitormattos marked this pull request as ready for review November 15, 2026 17:18
@vitormattos
vitormattos merged commit 22fc564 into main Nov 15, 2026
41 of 44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant