# Frontend Spec — Maintenance Management Platform

**GPS Renewables · Operations & Maintenance Technology**
Source: current interactive design build (`Maintenance Platform with template.dc.html`), GPS WEB Design System.

---

## 1. Goal

Give site-based engineers and managers one system to raise, triage, work, and close maintenance activities across biogas/bio-CNG plants — with a full audit trail per record — while giving portfolio- and central-level roles read-only oversight across sites. The frontend must make role-appropriate actions obvious and everything else absent (not just disabled), enforce two safety gates (Permit to Work, checklist completion) before an activity can close, and keep every record's history visible alongside its data.

---

## 2. User and use case

| Role | Primary use case in this UI |
|---|---|
| Shift In Charge | Open "My Activities," work an assigned activity: link a PTW, tick off checklist items, add notes. |
| Maintenance Engineer | Raise a corrective activity; progress and close assigned work; record parts/work done. |
| Plant Manager | Triage the board, assign work, cancel activities, plan PM, configure their site. |
| Portfolio Manager | Review activity/equipment status and KPIs across their portfolio's sites; no editing. |
| Central Team | Review status across all sites; maintain central tags/disciplines/checklist templates. |
| Admin | Everything above, unrestricted, plus global configuration. |

Common thread: every role except the two read-only ones eventually lands on an **Activity detail** record — it is the app's core screen.

---

## 3. Page structure

Shell: fixed top bar (site context, search, notifications, user menu) + left nav, persistent on every authenticated screen. Left nav has two groups — **Operations** (Dashboard, Activities, Calendar, Equipment, Reports) and **Configure** (Site & Areas, Users & Teams, Maintenance Plan, Checklist Templates, Tags, Stages), the latter hidden entirely for roles that can't configure anything. Shift In Charge gets a single nav item ("My Activities") in place of the whole Operations group.

| # | Page | Structure |
|---|---|---|
| P1 | Dashboard | Role-scoped KPI cards + recent-activity summary; entry point after sign-in. |
| P2 | Activities | Shared filter bar → Board (Kanban columns per stage) / List / Calendar view toggle. Shift In Charge: list only, pre-filtered to "assigned to me." |
| P3 | Activity detail | Header (code, title, stage pipeline, PTW status) → key-fields panel → work/checklist panel → activity log docked alongside (right column desktop / tab on mobile). |
| P4 | Raise activity (modal) | Single short form over the current page. |
| P5 | Calendar | Month/week grid, activities plotted on scheduled date; create/reschedule inline. |
| P6 | Equipment register | Filterable list/grid grouped by area and tag. |
| P7 | Equipment detail | Profile fields + photo → reliability KPIs (MTBF/MTTR/failure dates) → activity history → documents. |
| P8 | Maintenance Plan | List of PM plans → create/edit form (equipment, recurrence, team, checklist). |
| P9 | Reports | Filter bar → KPI cards → charts/tables → export. |
| P10 | Site & Areas | Site profile fields + area tree/list. |
| P11 | Users & Teams | Users list + Teams list, each with a detail/edit panel. |
| P12 | Checklist Templates | List (Central/Site scope) → template editor (items, versioning). |
| P13 | Tags | Central tags / Site tags / Disciplines, three managed lists. |
| P14 | Stages | Ordered list of lifecycle stages with the closing-stage toggle. |

Supporting overlays (not standalone pages): Close-out modal, Cancel-activity modal, PTW link/draft modal, Checklist picker/one-off builder, Notification centre (slide-over from the bell).

---

## 4. Component behavior

**Stage pipeline (activity header)** — clickable breadcrumb of configured stages; clicking a later stage attempts that transition and is subject to the same gates as a drag-drop on the board.

**Kanban board** — cards draggable between stage columns. Dropping into "In Progress" or the closing stage triggers the PTW/checklist gate checks before the drop commits; a blocked drop snaps the card back and opens the relevant modal (PTW or checklist panel) instead.

**Close-out modal** — two required fields: actual time (pre-filled, editable) and PTW reference (pre-filled if already linked, otherwise entered here). Confirm is disabled until both are present; confirming closes the activity, feeds MTTR, and posts one system log entry covering both fields.

**Cancel-activity modal** — reason (fixed-list select, required) + note (free text, required). Confirm disabled until both are filled. Only reachable by Plant Manager, only from an open (non-terminal) stage.

**PTW modal** — two tabs/modes: Search (query the external register by reference/type/equipment, select a result) and Draft (permit type + scope of work, creates a reserved draft). Either path, on confirm, sets the activity's PTW reference and posts a log entry.

**Checklist panel** — one row per item; type-appropriate input (text field / single-select / multi-select / checkbox). Each item shows its assignee; recording a value stamps who recorded it and posts a log entry. Items assigned to the signed-in user are highlighted. Attempting to close with outstanding items shows a toast/inline count and scrolls to the first outstanding item.

**Activity log ("Chatter")** — two composer buttons (Log note / Send message) expand a rich-text box with @mention and file attach; a Messages/History filter toggles the feed; feed groups by day with date separators and a "load older" affordance at the bottom. System entries render as compact one-line rows (actor, field, from → to, timestamp), visually distinct from note/message bubbles. To-dos pin above the regular feed until marked done.

**Filter bar** (Activities, Calendar, Reports) — site, team, engineer, equipment, type, priority, stage; shared component reused across the three screens; a "Save filter" affordance persists the current combination for reuse.

**View toggle (Board/List/Calendar)** — single shared control at the top of the Activities screen; not rendered at all for Shift In Charge (list is forced).

**Team/User pickers** — searchable select, scoped to the current site for site-scoped roles; project-grant multi-select for Central Team/Portfolio Manager/Admin user records.

---

## 5. Visual design

Governed by the GPS WEB Design System — Vuetify 3 base, Inter typeface, 4px spacing scale, MDI icons.

- **Color**: Primary green `#5fa414` reserved for highest-intent actions (primary CTAs, active nav pill, record IDs, completed stepper state). Green-MID `#28a745` = success/approve, Green-DARK `#006400` = confirmed/complete. Orange `#ffa500` = warning, DRAFT prefix, and Submitted status. Error `#f5524a` for validation/destructive; Red `#dc3545` reserved for age/overdue badges. Link color `#007bff` for file names, never the brand green.
- **Type**: Inter, weights 400/500/600/700; 0.5px letter-spacing across every token including body text; headings capitalized, body sentence-case; app-bar page title is 24px/700.
- **Backgrounds**: app background is flat neutral `#f2f2f2`, full bleed, no gradients/images. White is reserved for surfaces on top (cards, tables, modals, sidebar, app bar).
- **Corners**: buttons/chips/badges/active-nav pill fully rounded (9999px); cards, modals, inputs at 8px; tooltips at 4px.
- **Cards**: white, elevation-1, 8px radius, 16px padding; drop to elevation-0 with a 1px Text-10 border inside modals/expanded rows.
- **Borders**: single value, 1px solid `#e7e7e7`, used for every divider/input border; color only changes on focus (green) or error (red).
- **Iconography**: MDI glyphs only, 20–24px, no emoji, no illustrated icons.
- **Status/DRAFT convention**: DRAFT renders as an orange inline text prefix on the record ID, never as a chip; status words (Submitted, Pending, Approved, Completed, Rejected, Draft, Cancelled) are single capitalized tokens.

---

## 6. Responsive behavior

Desktop-first (target breakpoint lg, 1280px+); tablet/mobile degrade gracefully rather than being separately designed:

- **Activities board** → single-column list + a stage selector, replacing the multi-column Kanban.
- **Activity/Equipment detail** → stacks vertically; the activity log becomes a switchable tab instead of a docked side column.
- **Calendar** → collapses from month/week grid to an agenda (list-by-date) view.
- **Filter bar** → collapses into a bottom/side sheet triggered by a filter icon, instead of an inline row.
- **Sidebar nav** → remains present but does not collapse in MVP (per design system: sidebar is a fixed, non-collapsible 168px element on desktop; on narrow viewports it becomes a drawer).
- No dedicated small-screen redesign beyond the above — acceptable degradation, not a mobile-first rebuild.

---

## 7. Interaction states

- **Hover**: primary buttons darken via brightness(0.96), no lift/shadow change; icon buttons get a neutral-1 background fade and icon deepens to Text-80; table rows get a subtle `#fafafa` fill.
- **Press/active**: an additional brightness(0.92) step over hover; no translate or scale on any element.
- **Focus**: input borders swap from Text-10 to Primary green; no additional outer ring.
- **Loading**: skeleton loaders only, never a centered spinner, for any data fetch that can flash — `table-thead, table-row@N` for tables (N ≈ typical row count), `card` per KPI tile, `image, article` per chart card. Skeleton height approximates real content height to avoid layout jump.
- **Empty states**: subdued `#ededed` panel, 6px radius (web), centered MDI icon at 56px in Text-30, a short Text-50 label, and a one-line Text-60 helper with the action verb inlined as bold Primary-green text (never a rendered button inside the panel — the real action lives in the surrounding toolbar).
- **Disabled**: form/modal confirm actions are disabled (not hidden) until required fields are valid — applies to close-out, cancel, and PTW modals specifically.
- **Blocked transition**: dragging/clicking into a gated stage without a linked PTW or with outstanding checklist items does not silently fail — it opens the exact modal/panel needed to resolve the gate.
- **Toast/inline notification**: transient success/error via standard snackbar (floating, bottom-right); persistent non-blocking context (e.g., "not assigned to logbook") via an inline orange banner at the bottom of the content area — these are visually and behaviorally distinct patterns, not interchangeable.
- **Read-only role rendering**: Portfolio Manager and Central Team never see a disabled/greyed-out action — the control is not rendered at all on screens they can only view.

---

## 8. Data and edge cases

- **Cross-site access**: a record belonging to another site must be unreachable for a site-scoped user — no deep link, no search hit, not merely UI-hidden.
- **Actual-time pre-fill**: compute elapsed New→Done and In-Progress→Done, discard any candidate ≤10 minutes (guards against accidental instant closes corrupting MTTR), pre-fill the lower of what remains, and leave it editable.
- **Cancelled activities**: excluded from open-backlog counts and from MTBF/MTTR calculations; history is retained in full.
- **Area deletion**: blocked while any equipment is still assigned to that area.
- **Team deletion**: proceeds after an 8-second undo window rather than immediately.
- **Checklist template edits**: versioned — bumping the version never retroactively changes a checklist instance already attached to an in-flight activity; the template screen warns if a template is in-use (by a PM Plan) or has generated instances before allowing edit/deactivation.
- **Deactivation vs. deletion**: users, sites, PM plans, and checklist templates support deactivation that preserves history; hard delete is either blocked (areas) or not offered.
- **Immutable log**: no edit or delete on any log entry, ever — corrections must be new entries.
- **Multi-project users**: a user with more than one project grant displays a project list instead of a single home site field, everywhere a "site" would otherwise show.
- **Origin badge with no source module**: LLF/Breakdown origins reference a source record that may not exist yet (those modules are future) — the UI must handle a present origin badge with an absent/placeholder source link gracefully.
- **"Send message ... to followers" copy**: currently unresolved inconsistency — no follower list/avatars/count is rendered anywhere; treat as a copy fix, not a feature to build around, until product decides to rename it or add a real recipient concept.

---

## 9. Accessibility

- Sufficient color contrast and visible focus states on every interactive element (design system spec, not yet independently audited against WCAG level).
- All controls carry labels; icon-only buttons (MDI glyphs) require an accessible name, not just a visual glyph.
- Plain-language copy throughout — no jargon-dependent labels — supports both readability and screen-reader clarity.
- Gated actions (PTW required, checklist outstanding) must announce *why* an action is blocked, not just prevent it silently — this is a hard requirement given these are safety gates, not convenience validation.
- Read-only roles must not encounter dead/disabled controls that a screen reader would announce as actionable — absence, not disablement, is the pattern.
- Keyboard operability for drag-and-drop (Kanban stage changes) needs an equivalent non-drag path (e.g., the stage-pipeline breadcrumb click) — already part of the design, should be preserved as the accessible alternative.
- English-only for this release; no localization/RTL requirement.

---

## 10. Acceptance criteria

- A site-scoped user can only ever see, search, or deep-link into records belonging to their own site.
- Raising a corrective activity is completable in one short form and lands the user on the new record's detail view.
- An activity cannot be moved into "In Progress" or its closing stage without a linked PTW reference — attempting to do so always opens the PTW flow instead of completing silently or erroring.
- An activity cannot reach the closing stage while any checklist item is unrecorded — the block always names the outstanding count and routes the user to resolve it.
- Closing an activity always requires and captures both actual time and PTW reference in the same step, and always feeds equipment MTTR on confirm.
- Cancelling an activity is only available to Plant Manager/Admin, always requires a reason and a note, and always results in a Cancelled-stage record excluded from backlog/MTTR.
- Every tracked field change on an activity produces exactly one automatic, immutable system log entry — never zero, never manually logged instead.
- Portfolio Manager and Central Team never see a create/edit/assign/close/cancel control rendered anywhere in the operational screens.
- Central Team's only write actions anywhere are within Configure, and only for central-scope tags, disciplines, and checklist templates.
- Shift In Charge's nav, views, and available actions match the reduced set exactly (My Activities only, list view only, no raise/close/cancel).
- Deactivating a user/site/plan/template never deletes its historical records or its references from past activities.

---

## 11. Implementation constraints

- Target stack: **Vue 3 + Vuetify 3**, GPS theme (`theme.js`), MDI icon font, Inter variable font — no substitute UI framework or icon set.
- Authentication is Keycloak SSO only; no local username/password form is to be built.
- Authorization (role scoping) and the two lifecycle gates (PTW, checklist) must be enforced **server-side** — the frontend's hiding/blocking of controls is a UX layer, not the security boundary.
- Activity-log immutability is an append-only guarantee — the frontend must never expose an edit/delete affordance on a log entry, and the backend must not accept one either.
- "Project" and "Site" are currently 1:1 in the data — do not build UI that assumes they will always diverge, but don't hard-code the assumption that they never will (open item, see SRS §12 O10).
- No spare-parts inventory, purchase orders, contractor billing, or native mobile app in this release — don't scaffold UI for these; the data model leaves room but the frontend shouldn't anticipate them.
- Reports export is spreadsheet-format only; no PDF/BI-tool export path in scope.
- Skeleton-loader components must use the GPS-overridden bone fill (neutral-1 fill, white shimmer) from `kit.css` — do not use Vuetify's default skeleton coloring.

---

*End of document.*
