WP Manifestindependent plugin directory
manifest / users / uplinkportal

UplinkPortal

Public-core WordPress plugin for an MSP client portal: modular operations dashboard, client access control, and entitlement-backed integrations.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/uplinksync/uplinkportal/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

UplinkPortal is a WordPress plugin for a single-site MSP portal deployment where the MSP provider hosts the site and directs clients to it.

Product IA (Source of Truth)

Top-level admin sections:

  • Operations Dashboard
  • Agreements & Records
  • Service Catalog
  • Configuration
  • Tools & Diagnostics

Configuration is a single hub page with server-rendered tabs (admin.php?page=uplinkportal-settings&tab=<key>):

  1. Client Access
  2. Modules
  3. Security
  4. Company Info
  5. Portal Preview

Licensing is owned by Configuration > Modules > Database > Licensing. Only canonical admin routes and submenu slugs are registered.

Admin UI Style Direction

Admin pages follow an Enterprise / Modern SaaS direction while remaining WordPress-native:

  • Scoped wrapper: .uplinkportal-admin / .msp-admin only.
  • Shared tokens in assets/css/admin-console.css (--msp-space-*, --msp-radius, --msp-border, --msp-surface, --msp-surface-muted, --msp-text, --msp-text-muted, --msp-accent).
  • WP patterns first (nav-tab-wrapper, widefat, inline notices, button classes).
  • Module Catalog shows concise cards only: module name, short description, status, primary action.

Public-Core Boundary

This repository is public scaffolding.

  • Paid/proprietary logic is not implemented here.
  • Entitlement-sensitive behavior is delegated to secure backend/private add-ons.
  • Add-on module cards in this repo are UI scaffolds only.

Key Runtime Components

  • Entry point: uplinkportal.php
  • Runtime includes: includes/
  • Admin and settings: src/Admin/
  • Client portal: src/ClientPortal/
  • Core modules and support: src/Core/
  • Worker and infra helpers: infrastructure/

Client Access Data Model

Client access now uses custom WordPress tables (not user-meta/options for entitlement state):

  • *_uplinkportal_client_identity_map
  • *_uplinkportal_client_module_access
  • *_uplinkportal_client_feature_flags (optional feature-flag granularity)

Runtime schema management:

  • Activation hook: src/Core/Activator.php
  • Upgrade/runtime assurance: includes/class-main-module.php
  • Store: src/Core/Support/ClientAccessStore.php

Reference SQL:

  • infrastructure/wordpress/migrations/202602170001_client_access_tables.sql

Portal Preview Storage

Portal preview customization is stored in a private directory (not in public uploads):

  • Store: src/Core/Support/PortalCustomizationStore.php
  • Path: wp-content/uplinkportal-private/portal-preview/

Screenshots

Development

Requirements:

  • PHP 8.3+
  • WordPress 6.x

Commands:

npm install --no-save cspell
composer lint
composer test

CI

Workflows:

  • .github/workflows/ci.yml
    • PHP lint
    • Composer lint (PHPCS + cspell)
    • PHPUnit
    • repository hygiene scan (secrets/pro-boundary checks)
  • .github/workflows/release-plugin.yml
  • .github/workflows/db-migrate.yml
  • .github/workflows/deploy-worker.yml

Documentation

CI/CD

  • CI (GitHub Actions): PHP lint, Composer lint (PHPCS + cspell), PHPUnit, and a repository hygiene scan (secret + public-core boundary checks) run on every push and pull request. See .github/workflows/ci.yml.
  • Releases: .github/workflows/release-plugin.yml packages tagged builds.
  • Database & worker: .github/workflows/db-migrate.yml and .github/workflows/deploy-worker.yml provision the Supabase schema and the Cloudflare Worker used by entitlement-backed features.

main is protected: changes land through pull requests that must pass CI before they can be merged.

Contributing

Branch from main, open a pull request, and let CI run. Add tests for behavior changes and keep the public-core boundary intact (no proprietary/entitlement logic in this repository). Never commit literal secrets — use CI secrets and a runtime secret manager.

License

Distributed under the terms of the AGPL-3.0-or-later license.