v2 Admin Spec — Global Patterns

Global Patterns

Cross-cutting patterns and conventions used throughout the admin backend redesign. Domain-specific spec documents reference these patterns by name rather than re-specifying them.


1. Navigation Shell

1.1 Sidebar Structure

Layout: Fixed left sidebar, always visible. Collapsible to icon-only mode.

Sections (top to bottom):

  1. Logo/brand area (top)
  2. Global search bar
  3. Dashboard (standalone item, not grouped)
  4. 9 domain sections, each with an icon, label, and expandable sub-items:
    • Student Management (icon: users)
    • Semester Management (icon: calendar-check)
    • Content (icon: play-circle)
    • Scheduling (icon: clock)
    • Teacher Management (icon: user-check)
    • Billing & Payments (icon: credit-card)
    • Reporting (icon: bar-chart)
    • Communication (icon: mail)
    • Admin & System (icon: settings)

Expand/collapse behavior:

Active state: Current section header highlighted, current sub-item highlighted with left border accent

1.2 Breadcrumb Pattern

Format: Domain > Screen > [Entity Name] Examples:

Behavior: Each segment is clickable and navigates to that level. Entity names link to the entity page's default tab (Profile).

1.3 Page Header Pattern

Every page has:


2. Global Search

From Candidate C enhancement.

2.1 Placement and Access

2.2 Searchable Entities

Entity Searchable Fields Result Format
Student Name, email Name · Level · Semester · Status badge
TA Name, email Name · "Teaching Assistant" · Student count
Semester Name Name · Date range · Status badge

2.3 Result Behavior

2.4 Recent Searches


3. Role-Based Access

3.1 Role Definitions

Role Code Sidebar View Action Permissions
Admin user_type=1 Full 9-domain sidebar Full CRUD + bulk operations
Teaching Assistant (TA) user_type=2 4 items: My Students, My Schedule, My Groups, Recordings View assigned students, review submissions, manage own schedule
Admin (View Only) user_type=5, role_flag=view_only Full 9-domain sidebar View all, no create/edit/delete/bulk actions
Support Staff user_type=5, role_flag=support Full 9-domain sidebar View all including billing data, no billing actions

Implementation note: View-Only and Support Staff share user_type=5. A new role_flag column (or equivalent permission attribute) on the users table is required to differentiate them. The only behavioral difference is that Support Staff sees the Student Detail > Payments tab data (read-only) and billing domain screens, while View-Only also sees these but without the billing-specific context that Support Staff needs for student inquiries. In practice, both roles have identical view-only access; the distinction exists primarily for audit/logging purposes and potential future permission divergence.

3.2 Master Access Matrix

Domain Admin TA View-Only Support Staff
Dashboard Full Reduced (own alerts) View only View only
Student Management Full Own students only View only View only
Semester Management Full Hidden View only View only
Content Full Recordings only View only View only
Scheduling Full Own schedule only View only View only
Teacher Management Full Hidden View only View only
Billing & Payments Full Hidden View only View only (no actions)
Reporting Full Hidden View only View only
Communication Full Own messages only View only View only
Admin & System Full Hidden Hidden Hidden

3.3 TA Sidebar

TAs see a simplified sidebar:

├── My Students (→ Students list filtered to assigned students)
├── My Schedule (→ TA Schedules filtered to own schedule)
├── My Groups (→ Student Groups filtered to own groups)
└── Recordings (→ Content > Recordings)

3.4 Action Visibility Rules


4. Component Patterns

4.1 Data Table

Standard layout:

Column types:

4.2 Filter Bar

Layout: Horizontal bar above data table with:

Behavior:

4.3 Status Badges

Color scheme by domain:

Status Color Used For
Active Green Student status, subscription status, semester status
Inactive / Blocked Gray Deactivated student
Enrolled Blue Student semester status
Pass Green Student promotion status
Fail Red Student promotion status
Under Review Yellow/Amber Submission status
Reviewed Green Submission status
Past Due Orange Subscription payment status
Cancelled Gray Subscription status
Paused / Deferred Blue Subscription pause or deferment status
Incomplete Yellow/Amber Stripe subscription incomplete (initial payment failed)
Unpaid Red Stripe subscription unpaid (renewal payment failed, exhausted retries)
None Gray No Stripe subscription found for student
Pending Yellow/Amber Awaiting action (End Checklist steps, Setup Checklist steps)
Complete Green Workflow step completed
Draft Blue Semester not yet active (distinguishes from Inactive gray)

Communication statuses (used in Communication domain screens):

Status Color Used For
Draft Blue Unsent email or notification being composed
Scheduled Yellow/Amber Message queued for future send
Sent Green Message dispatched to recipients
Delivered Green Push notification confirmed delivered
Failed Red Message delivery failed
Read Green Private message read by recipient
Unread Yellow/Amber Private message not yet read

Issue Queue statuses (used in Admin & System > Issue Queue, per ADR-006):

Status Color Used For
Open Blue New, unread, unassigned issue
In Progress Yellow/Amber Admin is handling. May carry "Delegated to CS/IT/Teaching" sub-badge (gray text modifier, same amber pill).
Resolved Green Handled, kept in history
Rejected Red Not a real issue (spam, misfire, duplicate); kept in history. No hard delete.

Enrollment Type badges (used on Students list, Student Detail, Active Enrollment Report, per STAKEHOLDER-ANSWERS-2026-04-22 §C):

Status Color Used For
Continuing Blue Student was with us last semester, enrolling in something new (L1–4 graduate, or Year 2 progression)
New Green First-time enrollee
Repeat Yellow/Amber Repeating a level previously failed, or opted to redo
Year 2 Purple Currently in Year 2 program

Invoice-level statuses (used in Student Detail > Payments tab payment history, sourced from Stripe invoice.status):

Status Color Context
Paid Green Invoice fully paid
Open Yellow/Amber Invoice issued, awaiting payment
Void Gray Invoice voided (no longer collectible)
Uncollectible Red Invoice marked uncollectible (all retry attempts exhausted)

Payment transaction statuses (used in Billing & Payments > Payments screen, sourced from Stripe charge/payment intent status):

Status Color Context
Succeeded Green Payment charge succeeded
Failed Red Payment charge failed
Refunded Gray Payment refunded
Pending Yellow/Amber Payment processing

Note: Invoice statuses and payment transaction statuses are related but distinct. An invoice can be "Open" while its latest payment attempt "Failed." The Student Detail Payments tab shows invoice-level status (Stripe's canonical invoice lifecycle). The Billing > Payments screen shows transaction-level status (individual charge outcomes). Both are Stripe-sourced.

Badge format: Rounded pill with background color, white/dark text. Consistent across all screens.

4.4 Alert Tiles (Dashboard)

Layout: Standard Card (default shadcn styling, no custom borders or backgrounds) with:

Conditional display: Tiles only appear when count > 0 (except semester phase prompt, which is always visible)

Trend badge styling: Trend badges use a subtle background tint to signal direction:

Card and icon styling remains default throughout — no colored borders, tinted card backgrounds, or icon coloring. The trend badge background is the sole visual signal, keeping the layout clean and consistent with the component library.

4.5 Metric Cards

Layout: Small card with:

Used on: Payment Overview metrics bar, Dashboard quick stats

4.6 Confirmation Dialogs

Standard (non-destructive):

Destructive:

Used for: Delete, Deactivate, Reset Progress, Cancel Subscription, Linked Deactivation

4.7 Toast Notifications

Types:

Behavior: Auto-dismiss after 5 seconds. Appears top-right. Stacks if multiple.

4.8 Empty States

Layout:

Every screen must define its empty state message and suggested action in its spec.

4.9 Loading States

4.10 Modals

Standard layout:

Used for: Create forms, Edit forms, Preview content, Confirmation dialogs

4.11 Tabs (Entity Pages)

Layout:

Behavior:

4.12 Section Headers

Within a tab or screen:


5. Data Patterns

5.1 Stripe Data Fetching

Two strategies depending on context:

Context Strategy Latency Staleness
Student Detail > Payments tab Real-time Stripe API call 1-3 seconds Fresh
Dashboard alert tiles Webhook-cached in local billing_alerts table <100ms Up to event delay
Payment Overview metrics Webhook-cached + periodic sync <100ms Up to 15 min

5.2 Customer ID Resolution

When looking up a student's Stripe data, follow this chain:

  1. Check users.stripe_customer_id (populated for admin-created subscriptions)
  2. If empty, look up subscription_signups.pp_customer_id in FE database by user_id
  3. If neither exists, search Stripe by email via Customer::search()
  4. If found, backfill users.stripe_customer_id for future lookups

5.3 Data Staleness Indicators

When displaying Stripe data fetched in real-time:

5.4 Error Handling for External APIs


6. Inline Documentation Pattern

Addresses interview finding: "Navigation is unintuitive and undocumented" and admin's request for "clear inline documentation explaining what each feature does."

6.1 Tooltips

6.2 Field-Level Help Text

6.3 Section Documentation Blocks

6.4 Transition Hints (First 30 Days)


7. Key Business Rules (Reference)

Preserved from the current system. Domain specs must enforce these:

  1. Semester protection: Cannot delete a semester if students are enrolled
  2. Level progression: Level 0 → 1 → 2 → 3 → 4 → Year 2 (no skipping)
  3. Year 2 enrollment: Level 4 students must explicitly sign up for Year 2
  4. Passing threshold: 3.5 marks minimum to pass
  5. Submission flow: Under Review (0) → Reviewed (1) by TA
  6. Content scoping: All content is scoped to a semester
  7. Registration vs Active: Registration can be open before semester becomes active
  8. Active semester: is_current = 1 determines which semester's content is served
  9. TA assignment: Can be automated based on Teacher Assignment Criteria rules
  10. Password generation: Auto-generated, 4 characters, lowercase only
  11. Linked deactivation (NEW): Deactivating a student with an active subscription must cancel the Stripe subscription in the same operation