# projectsprav/dv-portal architecture

> Architecture diagram of the GitHub repository projectsprav/dv-portal, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/projectsprav/dv-portal
- Repository: https://github.com/projectsprav/dv-portal

## Overview

1. This is a Next.js App Router application with a clear split between UI routes, server-side actions, and small API endpoints. The app is built around operational workflows for a data-center/business management console rather than a generic content site.

2. The main user-facing areas are route-based feature screens under `src/app`: `cross-connects`, `dc-access`, `energy`, `invoices`, `racks`, `settings`, and `tickets`. These pages are backed by feature-specific React components in `src/components`, with a shared shell/layout in `AppLayout`, `Layout`, and `Providers`.

3. Business logic is concentrated in `src/app/actions`. Those server actions are organized by domain: `auth`, `dc-access`, `energy`, `adminEnergy`, `freshdesk`, and `xero`. This suggests the primary pattern is: UI triggers a server action, the action talks to persistence and/or external services, and the page refreshes from returned state.

4. PocketBase is the core backend data store and likely the system of record. Evidence includes `src/lib/pocketbaseClient.ts`, `pb_migrations/`, schema/rule inspection scripts, and many collection/user maintenance scripts. The app’s data layer is therefore anchored in PocketBase collections, record rules, and migrations rather than a separate SQL backend.

5. Authentication is a dedicated subsystem. There is a NextAuth route at `src/app/api/auth/[...nextauth]/route.ts`, shared auth helpers in `src/auth.ts`, and an `AuthContext` plus `Auth` component on the client side. The repo also includes admin/user creation and reset scripts, indicating user lifecycle management is partly operational and partly app-driven.

6. External integrations are isolated behind API routes and actions. Xero has its own auth/callback flow under `src/app/api/xero/auth` and `src/app/api/xero/callback`, plus an invoice PDF endpoint under `src/app/api/xero/invoice/[id]/pdf`. Freshdesk and Teams are also integrated, with a Teams webhook route at `src/app/api/webhooks/teams/route.ts`.

7. The invoice area has both server and client responsibilities. `src/app/invoices/page.tsx` and `CustomerInvoicesClient.tsx` imply server-rendered page entry points with a dedicated client component for interactive invoice browsing, while Xero endpoints handle the external accounting side of the same domain.

8. The data-center operational workflows appear centered on access and facility management. `dc-access`, `racks`, `cross-connects`, and `energy` likely model requests, inventory, and usage tracking, with shared forms such as `AccessRequestForm` and `CrossConnectOrderForm` feeding those flows into PocketBase-backed records.

9. The repository includes substantial schema and maintenance tooling. Files like `list-schema*.mjs`, `list-rules.mjs`, `fix-schema.mjs`, `update-rules*.mjs`, and `clean-records.mjs` indicate that record rules, collection definitions, and user data are actively managed outside the main app. This is an important architectural boundary: runtime app logic is separate from one-off admin/data repair scripts.

10. Deployment is containerized. The presence of `Dockerfile`, `docker-compose.yml`, and `docker/nginx/nginx.conf` shows the app can run behind Nginx in a containerized environment. Static assets live in `public/`, including images and a data-center video used by the UI.

11. From a diagram perspective, the key flow is: browser UI → Next.js page/component → server action or API route → PocketBase and/or external service (Xero, Freshdesk, Teams) → response back to the UI. The main integration boundaries are authentication, PocketBase persistence, and third-party service callbacks/webhooks.

Main entry points: [`src/components/AppLayout.tsx`](https://github.com/projectsprav/dv-portal/blob/main/src/components/AppLayout.tsx) (UI shell), [`src/lib/pocketbaseClient.ts`](https://github.com/projectsprav/dv-portal/blob/main/src/lib/pocketbaseClient.ts) (PocketBase), [`src/app/energy/page.tsx`](https://github.com/projectsprav/dv-portal/blob/main/src/app/energy/page.tsx) (Energy), [`src/app/actions/auth.ts`](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/auth.ts) (Auth actions)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_app["App UI"]
  node_n_home["Portal shell<br/>app entry<br/>[layout.tsx]"]
  node_n_layout["UI shell<br/>layout/components<br/>[AppLayout.tsx]"]
  node_n_overview["Overview<br/>dashboard<br/>[Overview.tsx]"]
  node_n_cross_connects["Cross-connects<br/>feature screen<br/>[page.tsx]"]
  node_n_dc_access["DC access<br/>feature screen<br/>[page.tsx]"]
  node_n_energy["Energy<br/>feature screen<br/>[page.tsx]"]
  node_n_invoices["Invoices<br/>feature screen<br/>[page.tsx]"]
  node_n_racks["Racks<br/>feature screen<br/>[page.tsx]"]
  node_n_settings["Settings<br/>feature screen<br/>[page.tsx]"]
  node_n_tickets["Tickets<br/>feature screen<br/>[page.tsx]"]
end

subgraph group_grp_actions["Server Actions"]
  node_n_auth_actions["Auth actions<br/>server actions<br/>[auth.ts]"]
  node_n_dc_actions["DC access actions<br/>server actions<br/>[dc-access.ts]"]
  node_n_energy_actions["Energy actions<br/>server actions<br/>[energy.ts]"]
  node_n_admin_energy["Admin energy<br/>admin actions<br/>[adminEnergy.ts]"]
  node_n_freshdesk_actions["Freshdesk actions<br/>integration actions<br/>[freshdesk.ts]"]
  node_n_xero_actions["Xero actions<br/>integration actions<br/>[xero.ts]"]
end

subgraph group_grp_api["API Routes"]
  node_n_nextauth_api["Auth API<br/>next auth route<br/>[route.ts]"]
  node_n_teams_webhook["Teams webhook<br/>webhook route<br/>[route.ts]"]
  node_n_xero_api["Xero API<br/>oauth/callback routes<br/>[route.ts]"]
end

subgraph group_grp_data["Data Layer"]
  node_n_pb_client[("PocketBase<br/>data client")]
  node_n_pb_migrations["Migrations<br/>schema history"]
end

subgraph group_grp_ops["Ops Tooling"]
  node_n_schema_tools["Schema tools<br/>admin scripts<br/>[list-schema.mjs]"]
  node_n_user_ops["User ops<br/>admin scripts<br/>[create_users.mjs]"]
end

subgraph group_grp_deploy["Runtime"]
  node_n_container["Container stack<br/>deployment"]
end

node_n_home -->|"uses"| node_n_layout
node_n_layout -->|"hosts"| node_n_overview
node_n_layout -->|"navigates"| node_n_cross_connects
node_n_layout -->|"navigates"| node_n_dc_access
node_n_layout -->|"navigates"| node_n_energy
node_n_layout -->|"navigates"| node_n_invoices
node_n_layout -->|"navigates"| node_n_racks
node_n_layout -->|"navigates"| node_n_settings
node_n_layout -->|"navigates"| node_n_tickets
node_n_home -->|"auth"| node_n_auth_actions
node_n_auth_actions -->|"session"| node_n_nextauth_api
node_n_cross_connects -->|"mutates"| node_n_dc_actions
node_n_dc_access -->|"mutates"| node_n_dc_actions
node_n_energy -->|"mutates"| node_n_energy_actions
node_n_energy -->|"admin"| node_n_admin_energy
node_n_tickets -->|"syncs"| node_n_freshdesk_actions
node_n_invoices -->|"syncs"| node_n_xero_actions
node_n_xero_actions -->|"oauth"| node_n_xero_api
node_n_freshdesk_actions -->|"notifies"| node_n_teams_webhook
node_n_auth_actions -->|"reads/writes"| node_n_pb_client
node_n_dc_actions -->|"reads/writes"| node_n_pb_client
node_n_energy_actions -->|"reads/writes"| node_n_pb_client
node_n_admin_energy -->|"reads/writes"| node_n_pb_client
node_n_xero_actions -->|"reads/writes"| node_n_pb_client
node_n_pb_client -->|"defined by"| node_n_pb_migrations
node_n_pb_migrations -->|"maintained by"| node_n_schema_tools
node_n_user_ops -->|"administers"| node_n_pb_client
node_n_container -->|"runs"| node_n_home

click node_n_home "https://github.com/projectsprav/dv-portal/blob/main/src/app/layout.tsx"
click node_n_layout "https://github.com/projectsprav/dv-portal/blob/main/src/components/AppLayout.tsx"
click node_n_overview "https://github.com/projectsprav/dv-portal/blob/main/src/components/Overview.tsx"
click node_n_cross_connects "https://github.com/projectsprav/dv-portal/blob/main/src/app/cross-connects/page.tsx"
click node_n_dc_access "https://github.com/projectsprav/dv-portal/blob/main/src/app/dc-access/page.tsx"
click node_n_energy "https://github.com/projectsprav/dv-portal/blob/main/src/app/energy/page.tsx"
click node_n_invoices "https://github.com/projectsprav/dv-portal/blob/main/src/app/invoices/page.tsx"
click node_n_racks "https://github.com/projectsprav/dv-portal/blob/main/src/app/racks/page.tsx"
click node_n_settings "https://github.com/projectsprav/dv-portal/blob/main/src/app/settings/page.tsx"
click node_n_tickets "https://github.com/projectsprav/dv-portal/blob/main/src/app/tickets/page.tsx"
click node_n_auth_actions "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/auth.ts"
click node_n_dc_actions "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/dc-access.ts"
click node_n_energy_actions "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/energy.ts"
click node_n_admin_energy "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/adminEnergy.ts"
click node_n_freshdesk_actions "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/freshdesk.ts"
click node_n_xero_actions "https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/xero.ts"
click node_n_nextauth_api "https://github.com/projectsprav/dv-portal/blob/main/src/app/api/auth/[...nextauth]/route.ts"
click node_n_teams_webhook "https://github.com/projectsprav/dv-portal/blob/main/src/app/api/webhooks/teams/route.ts"
click node_n_xero_api "https://github.com/projectsprav/dv-portal/blob/main/src/app/api/xero/callback/route.ts"
click node_n_pb_client "https://github.com/projectsprav/dv-portal/blob/main/src/lib/pocketbaseClient.ts"
click node_n_pb_migrations "https://github.com/projectsprav/dv-portal/blob/main/pb_migrations/1781477868_updated_dc_access_requests.js"
click node_n_schema_tools "https://github.com/projectsprav/dv-portal/blob/main/list-schema.mjs"
click node_n_user_ops "https://github.com/projectsprav/dv-portal/blob/main/create_users.mjs"
click node_n_container "https://github.com/projectsprav/dv-portal/tree/main/Dockerfile"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_n_home,node_n_layout,node_n_overview,node_n_cross_connects,node_n_dc_access,node_n_energy,node_n_invoices,node_n_racks,node_n_settings,node_n_tickets toneBlue
class node_n_auth_actions,node_n_dc_actions,node_n_energy_actions,node_n_admin_energy,node_n_freshdesk_actions,node_n_xero_actions toneAmber
class node_n_nextauth_api,node_n_teams_webhook,node_n_xero_api toneMint
class node_n_pb_client,node_n_pb_migrations toneRose
class node_n_schema_tools,node_n_user_ops toneIndigo
class node_n_container toneTeal
```

## Components

### App UI

Route-based screens and shared client-side shell components.

- [Portal shell](https://github.com/projectsprav/dv-portal/blob/main/src/app/layout.tsx): app entry · Root route and shared app layout that frame the console experience. · `src/app/layout.tsx`
- [UI shell](https://github.com/projectsprav/dv-portal/blob/main/src/components/AppLayout.tsx): layout/components · Shared application wrappers, providers, and authenticated shell. · `src/components/AppLayout.tsx`
- [Overview](https://github.com/projectsprav/dv-portal/blob/main/src/components/Overview.tsx): dashboard · Main landing dashboard for the operational portal. · `src/components/Overview.tsx`
- [Cross-connects](https://github.com/projectsprav/dv-portal/blob/main/src/app/cross-connects/page.tsx): feature screen · Route and page component for cross-connect ordering/workflows. · `src/app/cross-connects/page.tsx`
- [DC access](https://github.com/projectsprav/dv-portal/blob/main/src/app/dc-access/page.tsx): feature screen · Route and page component for access requests and facility entry workflows. · `src/app/dc-access/page.tsx`
- [Energy](https://github.com/projectsprav/dv-portal/blob/main/src/app/energy/page.tsx): feature screen · Route and page component for energy monitoring and facility usage workflows. · `src/app/energy/page.tsx`
- [Invoices](https://github.com/projectsprav/dv-portal/blob/main/src/app/invoices/page.tsx): feature screen · Invoice browsing page with a dedicated client-side interaction layer. · `src/app/invoices/page.tsx`
- [Racks](https://github.com/projectsprav/dv-portal/blob/main/src/app/racks/page.tsx): feature screen · Route and page component for rack inventory and management. · `src/app/racks/page.tsx`
- [Settings](https://github.com/projectsprav/dv-portal/blob/main/src/app/settings/page.tsx): feature screen · Route and page component for configuration and admin settings. · `src/app/settings/page.tsx`
- [Tickets](https://github.com/projectsprav/dv-portal/blob/main/src/app/tickets/page.tsx): feature screen · Route and page component for support ticket workflows. · `src/app/tickets/page.tsx`

### Server Actions

Domain actions invoked from the UI to perform writes, orchestration, and external calls.

- [Auth actions](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/auth.ts): server actions · Authentication-related server actions and session helpers. · `src/app/actions/auth.ts`
- [DC access actions](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/dc-access.ts): server actions · Server actions for access requests and related facility workflows. · `src/app/actions/dc-access.ts`
- [Energy actions](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/energy.ts): server actions · Server actions for energy data and facility-side updates. · `src/app/actions/energy.ts`
- [Admin energy](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/adminEnergy.ts): admin actions · Administrative energy actions used for higher-privilege workflows. · `src/app/actions/adminEnergy.ts`
- [Freshdesk actions](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/freshdesk.ts): integration actions · Server actions that coordinate with the support system. · `src/app/actions/freshdesk.ts`
- [Xero actions](https://github.com/projectsprav/dv-portal/blob/main/src/app/actions/xero.ts): integration actions · Server actions for accounting and invoice synchronization. · `src/app/actions/xero.ts`

### API Routes

Next.js route handlers for auth, callbacks, and webhooks.

- [Auth API](https://github.com/projectsprav/dv-portal/blob/main/src/app/api/auth/[...nextauth]/route.ts): next auth route · NextAuth route handler for sign-in and session handling. · `src/app/api/auth/[...nextauth]/route.ts`
- [Teams webhook](https://github.com/projectsprav/dv-portal/blob/main/src/app/api/webhooks/teams/route.ts): webhook route · Inbound webhook endpoint for Microsoft Teams notifications. · `src/app/api/webhooks/teams/route.ts`
- [Xero API](https://github.com/projectsprav/dv-portal/blob/main/src/app/api/xero/callback/route.ts): oauth/callback routes · OAuth callback and invoice PDF endpoints for Xero integration. · `src/app/api/xero/callback/route.ts`

### Data Layer

PocketBase client, migrations, and schema/rule management.

- [PocketBase](https://github.com/projectsprav/dv-portal/blob/main/src/lib/pocketbaseClient.ts): data client · Shared PocketBase client used by the app and actions. · `src/lib/pocketbaseClient.ts`
- [Migrations](https://github.com/projectsprav/dv-portal/blob/main/pb_migrations/1781477868_updated_dc_access_requests.js): schema history · PocketBase migration history for collections and record rules. · `pb_migrations/1781477868_updated_dc_access_requests.js`

### Ops Tooling

One-off scripts for users, schema repair, and record maintenance.

- [Schema tools](https://github.com/projectsprav/dv-portal/blob/main/list-schema.mjs): admin scripts · Scripts for listing, fixing, and updating PocketBase collections and rules. · `list-schema.mjs`
- [User ops](https://github.com/projectsprav/dv-portal/blob/main/create_users.mjs): admin scripts · Scripts for creating, cloning, resetting, and repairing users. · `create_users.mjs`

### Runtime

Container and reverse-proxy deployment assets.

- [Container stack](https://github.com/projectsprav/dv-portal/tree/main/Dockerfile): deployment · Docker and Nginx runtime used to host the portal. · `Dockerfile`

## Connections

- Portal shell → UI shell: uses · Root app is rendered through the shared shell and providers.
- UI shell → Overview: hosts · Shared shell frames the overview dashboard and feature screens.
- UI shell → Cross-connects: navigates · Shell routes users into the cross-connect workflow.
- UI shell → DC access: navigates · Shell routes users into the data-center access workflow.
- UI shell → Energy: navigates · Shell routes users into energy monitoring screens.
- UI shell → Invoices: navigates · Shell routes users into invoice browsing.
- UI shell → Racks: navigates · Shell routes users into rack management.
- UI shell → Settings: navigates · Shell routes users into settings and admin controls.
- UI shell → Tickets: navigates · Shell routes users into ticket workflows.
- Portal shell → Auth actions: auth · App authentication flows are coordinated through server actions and helpers.
- Auth actions → Auth API: session · Authentication actions rely on the NextAuth route handler.
- Cross-connects → DC access actions: mutates · Cross-connect and access style forms submit through domain actions.
- DC access → DC access actions: mutates · Access request UI is backed by dc-access server actions.
- Energy → Energy actions: mutates · Energy UI uses server actions for read/write workflows.
- Energy → Admin energy: admin · Privileged energy views and maintenance use admin actions.
- Tickets → Freshdesk actions: syncs · Ticket workflows coordinate with Freshdesk through actions.
- Invoices → Xero actions: syncs · Invoice UI aligns with Xero-backed accounting workflows.
- Xero actions → Xero API: oauth · Xero actions depend on Xero auth, callback, and PDF endpoints.
- Freshdesk actions → Teams webhook: notifies · Support workflows can emit or receive Teams notifications.
- Auth actions → PocketBase: reads/writes · Auth and user lifecycle operations persist in PocketBase.
- DC access actions → PocketBase: reads/writes · Facility workflows store records in PocketBase.
- Energy actions → PocketBase: reads/writes · Energy workflows use PocketBase as the system of record.
- Admin energy → PocketBase: reads/writes · Administrative energy flows operate on PocketBase data.
- Xero actions → PocketBase: reads/writes · Invoice/accounting state is synchronized with PocketBase records.
- PocketBase → Migrations: defined by · Runtime collections and rules evolve through migrations.
- Migrations → Schema tools: maintained by · Schema maintenance scripts inspect and repair PocketBase structure.
- User ops → PocketBase: administers · User lifecycle scripts operate on the same PocketBase-backed identity store.
- Container stack → Portal shell: runs · Container and reverse-proxy runtime hosts the Next.js app.
