Skip to main content

Professional Services Automation (Implementation Portal)

Source-backed overview for apps/backend/src/implementation-portal/.

The backend module is named implementation-portal. Product and MCP-facing wording may use PSA.

For deeper operational diagnostics, see:

  • dev/runbooks/implementation-portal-troubleshooting

What this module provides

  • guide template management (phases and steps)
  • implementation boards cloned from templates
  • staff execution workflows (status, assignees, due dates, time, attachments, comments)
  • OTP-secured client portal interactions
  • invoice-draft generation and send flow

Architecture map (hexagonal)

LayerKey codepathsResponsibility
Domaindomain/entities/*, domain/services/*, domain/ports/*Core business rules and contracts
Applicationapplication/use-cases/*Workflow orchestration over ports
Infrastructureinfrastructure/persistence/kysely/*, storage/payment/notification adapters, cron processorDB and third-party adapters
Interfacesinterfaces/http/*, DTOs, guardsHTTP endpoints and request adapters

Rule of thumb:

  • Domain/application define behavior.
  • Infrastructure performs I/O (DB, Stripe, GCS, SendGrid).

Public interfaces (high-level)

Team-facing APIs

  • guide-template.controller.ts
  • implementation-board.controller.ts
  • board-step.controller.ts
  • invoice-draft.controller.ts

Client-facing APIs

  • client-portal.controller.ts
  • portal-session.guard.ts for write routes

Core workflows

1) Template to board

  1. Create guide template.
  2. Create board with optional template.
  3. BoardFactoryService clones phases/steps and applies due offsets.

2) Execution

  • Team updates step lifecycle and assignments.
  • Time entries recorded on hourly steps.
  • Attachments and comments recorded per step.

3) Client portal

  1. Client opens /portal/:shareToken.
  2. Client requests OTP and verifies OTP.
  3. Client writes through session-guarded routes.

4) Invoice flow

  1. Generate invoice draft from unbilled eligible steps.
  2. Review/edit line-item descriptions.
  3. Send via payment adapter (Stripe integration point).
  4. Track sent/paid/void states.

Important constraints from source

  • Document steps require at least one attachment before completion.
  • Time entries:
    • only allowed on hourly steps
    • minimum 0.25 hours
  • Step attachment max size: 50 MB (STEP_ATTACHMENT_MAX_BYTES).
  • Team cannot edit/delete time entries once step is linked to an invoice draft.
  • Client comments are persisted as client_visible.

Invoice calculation rules (InvoiceCalculatorService):

  • non_billable: excluded
  • fixed: include when step is completed|approved|client_approved
  • milestone: only approval steps in approved|client_approved
  • hourly: sum(timeEntry.hours) * hourlyRate in eligible statuses

Health model

OverdueCheckerService:

  • green: 0 overdue
  • yellow: 1-2 overdue
  • red: 3+ overdue OR stale board (>7 days without step updates)

Multi-tenancy and authorization

  • Team APIs scoped by :businessId.
  • Policy decorators enforce GuideTemplate, ImplementationBoard, BoardStep, and InvoiceDraft actions.
  • Client write operations require valid portal session token (header or cookie path).