Plugin Framework Specification

1. Purpose & Scope

The purpose of the plugin framework is to allow new, self-contained features to be added to the booking application without changing the core domain logic.

A plugin is a piece of functionality that can be attached to a booking or basket item (e.g. seat upgrade, carbon offset) and participate in key lifecycle events such as viewing a booking and completing payment.

1.1 In Scope

  • Backend plugin contract and lifecycle events.
  • Plugin discovery and dispatch on key events.
  • Data contract for what is sent to the frontend.
  • Frontend (Angular) rendering of plugin components.
  • Configuration and management of plugins.

1.2 Out of Scope

  • The detailed business rules of individual plugins.
  • Payment provider integration.
  • General booking domain logic (which remains in the core application).

2. Definitions

  • Plugin – A feature implemented independently that can be attached to a booking/basket item.
  • Plugin instance – The association of a plugin type with a specific booking/basket item.
  • Plugin key – A unique string identifier of the plugin type (e.g. seat-upgrade).
  • Plugin host – The core application that invokes plugins and renders their UI.
  • Frontend component key – The key used on the frontend to resolve an Angular component for a plugin.

3. Backend Plugin Framework

3.1 Plugin Contract

All plugins MUST implement a shared interface:

```csharp public interface IBookingPlugin { /// Unique identifier for the plugin type (e.g. “seat-upgrade”). string PluginKey { get; }

/// Static metadata for this plugin type (display name, description, etc.).
PluginMetadata GetMetadata();

/// Called when a booking/basket is viewed to generate UI data.
Task<PluginViewModel> OnViewedAsync(PluginViewContext context);

/// Called when payment is successfully confirmed.
Task OnPaymentReceivedAsync(PaymentEventContext context);

/// Optional: called when booking is cancelled/refunded.
Task OnBookingCancelledAsync(BookingCancelledContext context); }