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.

by UplinkPortal Contributors · github.com/uplinksync/uplinkportal · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/uplinksync/uplinkportal/archive/refs/heads/main.zip

Readme

UplinkPortal

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.

Read the full README on GitHub →