> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuro-tech.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Parklet backend architecture

> High-level architecture of the Parklet Neuron backend

Parklet is a Neuron assembly package hosted by `Waher.IoTGateway`. The backend is composed in `TAG.Service.Parklet`, exposed over HTTP through `TAG.Service.Parklet.Http`, and centered on domain services in `TAG.Service.Parklet.Core`.

## Runtime shape

At startup, `ParkletModule` creates a `ControllerEndpointRouter` mounted at `/parklet-api` with `SnakeCaseParameterNameCodec`.

The module then:

1. Registers account and anonymous authentication schemes on the router.
2. Creates repositories, reference-data providers, domain services, hydrators, payment collaborators, entitlement services, and authorization services.
3. Registers those dependencies in `router.ServiceProvider`.
4. Creates `ParkletHttpService`, which adds `/open-api`, request logging middleware, and scans the HTTP assembly for controllers.
5. Registers the router with `Gateway.HttpServer`.
6. Starts background work such as event dispatching, reservation lifecycle tracking, debt payment scheduling, and Stripe subscription processing.

`Stop()` reverses the runtime pieces by unregistering the router and disposing or stopping the long-running workers.

## Project layers

| Project                                                          | Responsibility                                                                                                         |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `TAG.Service.Parklet`                                            | Neuron module, package manifest, startup composition, router registration, background worker lifecycle                 |
| `TAG.Service.Parklet.Core`                                       | Domain models, service contracts, business services, authorization constants, shared result/page models, domain events |
| `TAG.Service.Parklet.Persistence`                                | Repository implementations, persistence models, and mappers for stored Parklet data                                    |
| `TAG.Service.Parklet.Http`                                       | HTTP controllers, request/response DTOs, hydrators, request authorization, middleware, and OpenAPI annotations         |
| `TAG.Service.Parklet.Entitlements`                               | Entitlement tiers, resource limits, usage checks, and entitlement-aware service wrappers                               |
| `TAG.Service.Parklet.Messaging`                                  | Persisted event publisher, persisted queue dispatcher, retry logic, and event handler invocation                       |
| `TAG.Service.Parklet.Tests` and `TAG.Service.Parklet.Http.Tests` | Domain and HTTP tests around services, authorization, hydrators, and controllers                                       |

## Request flow

An HTTP request enters through `Gateway.HttpServer` and is routed to `/parklet-api/...`.

The HTTP router then:

1. Matches the request method and route.
2. Runs route middleware and authorization middleware in pipeline order.
3. Creates a controller instance for the request through `router.ServiceProvider`.
4. Binds route, query, and JSON body values using the router's snake-case naming codec.
5. Calls the controller action.
6. Lets the controller call Core services and repositories through injected dependencies.
7. Hydrates domain models into HTTP response DTOs and returns JSON.

The controllers are intentionally thin. Most business rules live in Core services such as parking, reservations, leases, groups, queues, organizations, users, payments, and principals. Hydrators keep HTTP response shapes separate from domain models.

Parklet uses parent controllers for nested resources. For example, `ParkingAreaController` is declared under `ParkingAreasController`, and `ParkingSquaresController` is declared under `ParkingAreaController`, producing routes such as `/parklet-api/parking-areas/[areaId]/squares/[squareId]`. The same pattern appears under `/me`, `/groups/[groupId]`, and `/principals/[principalId]`.

## Authorization model

Parklet uses router authentication schemes to identify what kinds of callers the API accepts, then uses attribute-based authorization for endpoint permissions.

`ParkletAuthorization` resolves request facts into an ABAC subject and context. `ParkletAuthorizationMiddleware` bridges the HTTP router authorization pipeline to the Parklet authorization service. The shared `ParkletController` base class gives controllers helpers for asserting the current principal, user, authorization state, and service results.

This keeps endpoint code focused on the use case while authorization policy, role lookup, and request fact resolution stay centralized.

## Events and background work

Core services publish domain events through `IParkletEventPublisher`. The default publisher writes events to a persisted `DatabaseQueue`, and `PersistedQueueEventDispatcher` dequeues events, discovers matching `IParkletEventHandler<T>` implementations through the runtime inventory, and invokes them with retry handling.

The module also starts specialized background workers:

* reservation lifecycle tracking, which advances reservation state based on runtime settings
* debt payment scheduling, which processes outstanding ledger debt through the payment gateway
* Stripe subscription event dispatching for lease subscription changes

These workers are started after the dependency graph is registered and stopped during module shutdown.

## OpenAPI endpoint

`ParkletHttpService` exposes `/parklet-api/open-api` as a live OpenAPI document endpoint.

It calls `OpenApiGenerator.Generate(router, new OpenApiInfo { Title = "Parklet API", Version = "3.0.0" })`, adds the current Neuron server URL with `OpenApiGenerator.CurrentServers()`, and returns the generated document as JSON.

The generated document reflects the current router tree, controller routes, bound request/response types, authentication metadata, authorization metadata, and OpenAPI annotations such as `[Summary]` and `[Tag]`.

## Where to add behavior

* Add new business rules in `TAG.Service.Parklet.Core`.
* Add storage behavior behind Core repository contracts in `TAG.Service.Parklet.Persistence`.
* Add external HTTP surface area in `TAG.Service.Parklet.Http` controllers, requests, responses, and hydrators.
* Register new long-lived dependencies in `ParkletModule.Start()` before controller discovery.
* Publish cross-cutting side effects as domain events when the work should happen outside the request's main transaction.
