System Admin
Help Center
Platform management, user administration, and operations
Introduction
The System Administrator role is the highest privilege level on the MORSL platform. System Administrators have unrestricted access to all administrative pages and can modify any record in the system. This guide documents every section of the admin panel, the actions available in each, and the rules that govern automated processes.
Admin panel access
The admin panel is accessible from the account dropdown in the top navigation bar. System Administrators see a "System admin" link which leads to the admin dashboard at /public/admin/dashboard.php. The left-side admin navigation bar is present on all admin pages and provides quick access to every section.
Navigation structure
| Group | Pages |
|---|---|
| Platform | Users, Boards, Events, Organizations, Regions, CSV Import |
| Logs | Audit, Communications, Error, SMS / Messages, Cleanup |
| Engagement | Custom Pricing, Popup Messages, AI Tuning |
| Feedback | Feedback Inbox (accessible from the dashboard) |
| Top bar | Dashboard link always visible |
Dashboard
The admin dashboard (/public/admin/dashboard.php) is the landing page for system administrators. It provides a real-time snapshot of platform health and activity.
2.1 Platform Metrics
Six count tiles at the top display live totals queried directly from the database:
| Tile | What it counts |
|---|---|
| Users | Total registered user accounts in the user table. |
| Boards | Total boards across all statuses. |
| Postings | Total opportunity postings across all boards. |
| Replies | Total replies submitted across all postings. |
| Subscriptions | Total subscription records. |
| Feedback messages | Total inbound feedback emails received across all mailboxes. |
2.2 Activity Charts
Time-series charts below the metric tiles show day-by-day activity trends for key tables (users, boards, postings, replies), generated from created_at timestamps grouped by date. They help identify spikes, drops, or unusual patterns in platform activity.
2.3 Feedback Summary
A feedback panel shows aggregate email inbox statistics: total messages, unread count, open messages (OPEN / NEW / PENDING / IN_PROGRESS), resolved messages (RESOLVED / CLOSED), active mailboxes, and last sync timestamp. The eight most recently received emails are listed below, showing subject, sender, timestamp, status, priority, and mailbox. Click any item to open the full message in the Feedback Inbox.
Users
The Users page (/public/admin/users.php) lists all registered accounts with tools for searching, filtering, sorting, and managing individual users.
3.1 Searching and Filtering
- Text search — matches against name, email, organisation, and plan level fields
- Plan level filter — dropdown populated from distinct plan values in the database
- Active status filter — show all users, active only, or inactive only
- Rows per page — 10, 25, 50, or 100
All columns are sortable by clicking the column header. Sort direction toggles on repeated clicks.
3.2 User Table Columns
| Column | Contents |
|---|---|
| ID | Unique numeric user ID. |
| Name | First and last name. Links to the user edit page. |
| Registered email address. | |
| Plan | Subscription plan level (e.g. STANDARD, ENTERPRISE). |
| Active | Green Yes / grey No badge showing is_active status. |
| Actions | Inline action buttons for quick operations without leaving the list. |
3.3 Inline Actions
| Action | What it does |
|---|---|
| Toggle active | Flips the user's is_active flag between 1 and 0. Active users can sign in; inactive users are blocked. The change takes effect immediately. |
| Toggle SMS opt-in | Toggles the user's SMS consent status (sms_opt_in column). Controls whether the user receives SMS outreach from the AI matching system. |
3.4 Editing a User
Click a user's name or the Edit button to open the user edit page (user_edit.php). From there you can modify all profile fields: name, email, phone, plan level, subscription details, UI preferences, and role assignments. All changes are logged to the audit trail.
Boards
The admin Boards page (/public/admin/boards.php) provides full board management: creating new boards, viewing all existing boards with statistics, and managing access control.
4.1 Creating a Board
The Create Board form accepts:
- Board name (required, max 240 characters)
- Parent event, organisation, or region — at least one must be selected to define the board's hierarchy position (scope_type and scope_id)
- Available start date and available end date — control when the board is open for posting
- Keep alive (days) — extends the active period beyond the available end date; only applies when an Event is selected as the parent
- Community Administrator — selects the user who will manage incentives; they are automatically inserted into board_role as COMMUNITY_ADMIN and notified by email and SMS
- Board Access Control List — one or more user-role pairs granting Members, Moderators, or Community Admins access
- Status — ACTIVE, INACTIVE, or PENDING
4.2 Board List Views
The board list can be toggled between Grid and List view. Both views show: board name, hierarchy, availability dates, community admin, member/post/reply counts, keep-alive and effective-end dates. The Edit button opens the board edit page.
4.3 Board Hierarchy
| Scope type | Parent entity | Typical use |
|---|---|---|
| EVENT | An event record | Boards tied to a specific conference or summit with a defined end date and keep-alive period. |
| ORGANIZATION | An organisation record | Boards for a specific company, fund, or institution. |
| REGION | A region record | Boards scoped to a geographic area (country, state, metro). |
Events
The Events page (/public/admin/events.php) manages event records that serve as parent scopes for boards.
5.1 Event Fields
| Field | Purpose |
|---|---|
| Name | Display name for the event (required). |
| Post cutoff date | The date after which members may no longer view or post on boards scoped to this event. Boards past cutoff return a 403 error to members. |
| Sector / Industry group / Industry | Three-level GICS-style classification (sector code → industry group → industry). Used by the AI matching system to align postings with member profiles. |
| Assigned admin users | Users associated with administering this event. |
5.2 Post Cutoff Enforcement
When a member attempts to open a board whose parent event has passed the post_cutoff_date, the platform returns a 403 response. System administrators are not affected by this restriction and can always access boards regardless of cutoff status.
Organizations
The Organizations page (/public/admin/organizations.php) manages organisation records. Organisations can be assigned as parent scopes for boards and are linked to users as their affiliated company.
Each organisation record holds a name, optional description, and associated metadata. The organisation edit page (organization_edit.php) allows full editing of all fields. Changes are recorded in the audit log.
When creating a board with scope_type ORGANIZATION, the organisation is selected as the parent. The board inherits the organisation's context and the admin board list displays the organisation name in the Hierarchy column.
Regions
The Regions page (/public/admin/regions.php) manages the geographic hierarchy used to scope boards and classify member profiles. The region tree is stored in the us_geo_tree table.
7.1 Geographic Tree Structure
Regions are organised in a three-level hierarchy rendered as a collapsible tree view:
- Macro region — WEST, CENTRAL, or EAST
- State — US state name
- Metro — metropolitan area within the state
"Expand all" and "Collapse all" controls are available at the top of the tree. A live search box filters the tree in real time as you type, highlighting matching metro names.
7.2 Managing Region Records
- Add a new metro region by selecting a macro region and state, entering a metro name and display order, then clicking Add
- Edit an existing region record inline
- Delete a region record (all boards scoped to the deleted region will lose their parent reference)
All region mutations are logged to the audit trail.
CSV Import
The CSV Import page (/public/admin/imports.php) allows bulk loading of user and board data from comma-separated value files. The page provides template download links so administrators can prepare files in the correct format before uploading.
8.1 Import Process
Log Pages
Four log pages provide visibility into platform activity, communications, errors, and SMS messaging. All log pages are read-only — no modifications can be made from these pages.
Audit Log
Records every significant action by any user or automated process. Captures event type, entity type and ID, user ID, timestamp, and payload JSON.
Communications Log
All outbound email and notification activity: recipient, message type, subject/summary, send timestamp, and delivery status.
Error Log
PHP exceptions, unhandled errors, and application-level error events: error message, file and line number, severity level, and timestamp.
SMS Log
All outbound SMS via Vonage: recipient phone (E.164), message body, direction, type, provider message ID, delivery status, board ID, and user ID.
9.1 Audit Log Detail
The Audit Log (/public/admin/audit_logs.php) records:
- Event type (e.g. CREATE_POST, LINK_INCENTIVE, ADMIN_CREATE_BOARD)
- Entity type and entity ID (the record that was affected)
- User ID of the actor
- Timestamp and payload JSON with contextual details
This is the primary tool for investigating user activity, diagnosing data anomalies, and confirming that automated processes ran correctly.
9.4 SMS Log Detail
The SMS Log (/public/admin/sms_logs.php) is the primary tool for verifying SMS delivery, investigating failed sends, and auditing which users received SMS outreach for which boards and postings. Each entry captures recipient, message body, direction (OUTBOUND), message type, provider (VONAGE), provider message ID, delivery status, board ID, and recipient user ID.
Data Management (Cleanup)
The Cleanup page (/public/admin/cleanup.php) provides two automated maintenance jobs that keep board status data consistent with board lifecycle rules. Both jobs are manual — they run only when explicitly triggered by a system administrator.
10.1 Deactivate Expired Boards
available_end_dateDATE_ADD(available_end_date, INTERVAL days_keep_alive DAY) ≤ CURDATE()Before clicking Run, the table lists every board that would be affected, showing: ID, Board name, Current status, Available end date, Keep alive days, Expires on (computed), and Updated timestamp. Review this list carefully.
For each candidate: sets status to INACTIVE, sets updated_at to NOW(), and writes a BOARD_EXPIRED_DEACTIVATED audit event. All updates run in a single database transaction — if any row fails, the entire batch is rolled back.
Daily, or at minimum weekly. Safe to re-run — boards already INACTIVE are excluded from the candidate query.
10.2 Remove Pending Boards
status = PENDINGDATE(updated_at) ≤ DATE_SUB(CURDATE(), INTERVAL 5 DAY)Boards in PENDING status that have not been updated in 5+ days are considered stale — created but never activated.
For each candidate: sets status to INACTIVE, sets updated_at to NOW(), and writes a BOARD_PENDING_DEACTIVATED audit event. Runs in a single transaction with full rollback on failure.
Weekly is recommended. No automated schedule — runs only when manually triggered.
Popup Messages
The Popup Messages page (/public/admin/popup_messages.php) manages platform-wide announcement banners that appear to users when they sign in or navigate to certain pages.
11.1 Creating a Popup Message
Click "New popup message" to open the editor (popup_message_edit.php). A popup message record contains:
- Title — the headline of the announcement
- Body — rich text content of the message
- Target audience — all users, members only, or admins only
- Active from / Active to dates — the window during which the popup is shown
- Enabled / Disabled toggle — allows draft messages to be prepared and activated later
11.2 Managing Existing Popups
The popup list shows all messages with their status, date range, and audience. From the list you can edit any message or toggle it between enabled and disabled without opening the full editor. Expired messages remain in the list and can be reactivated by updating the date range.
Custom Pricing
Custom pricing is a two-page feature for managing enterprise subscription enquiries submitted through the public-facing pricing estimator.
12.1 Requests List
The requests list (/public/custom_pricing_list.php) supports search, status filter, sortable columns, sort direction toggle, and pagination (10 / 25 / 50 / 100 rows, defaulting to 25).
Status badges are colour-coded:
12.2 Custom Pricing Estimator
Click "Edit" on any request row to open the pricing estimator (/public/custom_pricing_estimator.php?id=N). The estimator computes a price proposal from four inputs:
- Min users / Max users — expected seat count range (max used for total estimate)
- Base seat price — list price per seat in dollars
- Discount rate — percentage discount to apply (0–100)
estimated_total = discounted_seat_price × max_users
Every save creates a version record in custom_pricing_estimate_history, preserving the full parameter set and the reviewing administrator's user ID. Opening a request for the first time automatically sets its status to IN_REVIEW.
Feedback Inbox
The Feedback Inbox (/public/admin/feedback_inbox.php) is the platform's internal email management system, connecting to one or more external mailboxes.
13.1 Mailbox Sync
| Control | Function |
|---|---|
| Sync All button | Triggers a concurrent sync of all active mailboxes. A concurrency selector (2–5 parallel syncs, defaulting to 3) controls how many mailboxes are fetched simultaneously. |
| Individual sync buttons | Each mailbox row has its own sync button for targeted refresh of a single mailbox. |
A progress card appears during sync showing: total completed, queued, running, failed counts, and a progress bar. The currently syncing mailbox name is displayed in real time.
13.2 Message Workflow
| Status value | Meaning |
|---|---|
| OPEN / NEW | Unactioned — requires attention. |
| PENDING | Waiting for more information or a follow-up action. |
| IN_PROGRESS | Being actively worked. |
| RESOLVED | Issue addressed; no further action needed. |
| CLOSED | Formally closed and archived. |
13.3 Mailbox Management
The Feedback Mailboxes page (/public/admin/feedback_mailboxes.php) manages IMAP/API connection credentials. Administrators can add new mailboxes, update credentials, toggle active/inactive, and set sync frequency. Inactive mailboxes are excluded from the Sync All operation.
AI Tuning Dashboard
The AI Tuning Dashboard (/public/admin/tuning_dashboard.php) provides administrative control over MORSL's AI-powered member-to-posting matching service, connecting to the external BulletinAI microservice via HTTP.
14.1 Service Health Panel
The top card shows the live status of the AI matching service, queried in real time on every page load:
- Online / Offline indicator — green dot (status: "ok") or red dot (unreachable or error)
- Reason generation mode — "rule-based" or "ai-generated"
- Sync timeout — maximum seconds the service waits for the MORSL API
- Top N — maximum number of candidate members returned per posting match run
A "Health JSON" link opens the raw /health endpoint response in a new tab for detailed diagnostic inspection.
14.2 Scoring Weights
The matching score is a weighted sum of three component scores. The weights must sum to 1.0. Two sliders control semantic and intent weights; the keyword weight is derived automatically.
The live readout updates as you drag the sliders. Click "Save weights" to push updated values to the AI service.
14.3 Rule Engine Parameters
The rule engine applies five sequential scoring layers on top of the base weights:
| Parameter | Description | Range | Default |
|---|---|---|---|
| Layer 2 min hits | Minimum keyword hits to pass the keyword screening gate. | 1–3 | 1 |
| Layer 3 min shared | Minimum shared industry/sector codes for taxonomy alignment. | 1–3 | 1 |
| Layer 4 mismatch penalty | Score deduction on detected sector or intent mismatch. | 0.00–0.20 | 0.08 |
| Layer 5 match bonus | Score addition on strong profile signal match. | 0.00–0.40 | 0.20 |
| Layer 5 mismatch penalty | Score deduction on negative signal detection. | 0.00–0.20 | ~0.08 |
Click "Save rules" to push updated rule parameters to the AI service. Weights and rules can be saved independently.
14.4 Match Logs
The lower section shows recent match run records from the ai_post_match_run table. Each entry shows: run ID, posting ID, composite score, semantic score, intent score, match status (MATCHED / EXCLUDED / BORDERLINE), and timestamp. Review these logs after any configuration change to confirm scores are in the expected range.