> Index de la documentation : https://stilldeeppos.com/fr/llms.txt

# StillDeep — API gRPC Reference

**Generated:** 2026-10-15T04:29:45+00:00
**Source:** `src/public/StillDeep.Intelligence.Contracts/protos/` (21 fichiers)
**Endpoint:** `localhost:50051` (HTTP/2, package `stilldeep.v1`)

Documentation generee automatiquement par `scripts/generate-grpc-docs.ps1`.
Ne pas editer manuellement — modifier les .proto + relancer le script.

## Sommaire

- [ageverification](#ageverification)
- [appointment](#appointment)
- [card](#card)
- [catalog](#catalog)
- [common](#common)
- [config](#config)
- [device](#device)
- [events](#events)
- [extensions](#extensions)
- [inventory](#inventory)
- [language](#language)
- [member](#member)
- [pos_proxy](#pos_proxy)
- [receipt](#receipt)
- [rental](#rental)
- [report](#report)
- [sales](#sales)
- [scheduling](#scheduling)
- [shift](#shift)
- [sync](#sync)
- [user](#user)

## ageverification

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/ageverification.proto`

> E005-S16 - AgeVerificationService : verification de l'age legal pour
> les produits restreints (alcool, tabac, cannabis dans les juridictions
> applicables).
> 
> Le service s'appuie sur :
>   * Member.custom_fields (ex : "date_of_birth") si client identifie.
>   * Saisie manuelle DOB par caissier si client anonyme.
>   * Plugin externe (ID scanner permis de conduire) qui injecte un DOB
>     via SourceKind.PLUGIN_SCANNER.
> 
> Le service NE STOCKE PAS le DOB pour les clients anonymes - juste le
> resultat (passed/failed) avec hash anonyme pour audit.
> 

### Services

#### `AgeVerificationService`

AgeVerificationService - verification d'age legal. Codes d'erreur : INVALID_ARGUMENT (aucune source DOB fournie ou format invalide), FAILED_PRECONDITION (verification passed=false), NOT_FOUND (product_id), PERMISSION_DENIED (manager_auth_token invalide). Le serveur logue toute verification dans system_audit_log avec hash anonymise pour conformite legale.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `VerifyAge` | `VerifyAgeRequest` | `VerifyAgeResponse` | - |
| `GetMinAgeForProduct` | `GetMinAgeForProductRequest` | `GetMinAgeForProductResponse` | - |

### Messages

- `AgeVerificationResult`
- `GetMinAgeForProductRequest`
- `GetMinAgeForProductResponse`
- `VerifyAgeRequest`
- `VerifyAgeResponse`

### Enums

- `VerificationSourceKind`

---

## appointment

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/appointment.proto`

> AppointmentService : rendez-vous de service (toilettage, coupe de griffes, soins).
> 
> Un rendez-vous occupe un employe qualifie pendant la duree du service plus son battement.
> La disponibilite croise les quarts planifies (user_schedule), les groupes de competence et les
> rendez-vous deja pris. L'encaissement passe par SalesService.AddItem(service_appointment_id).
> 

### Services

#### `AppointmentService`

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListAppointments` | `ListAppointmentsRequest` | `ListAppointmentsResponse` | - |
| `GetAvailability` | `GetAvailabilityRequest` | `GetAvailabilityResponse` | - |
| `CreateAppointment` | `CreateAppointmentRequest` | `AppointmentResponse` | - |
| `UpdateAppointment` | `UpdateAppointmentRequest` | `AppointmentResponse` | - |

### Messages

- `Appointment`
- `AppointmentResponse`
- `AvailableSlot`
- `CreateAppointmentRequest`
- `GetAvailabilityRequest`
- `GetAvailabilityResponse`
- `ListAppointmentsRequest`
- `ListAppointmentsResponse`
- `StaffDay`
- `TimeRange`
- `UpdateAppointmentRequest`

### Enums

- `AppointmentStatus`

---

## card

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/card.proto`

> CardService - cartes physiques / virtuelles : carte cadeau, carte fidelite,
> carte de rabais, carte employe, membership card.
> 
> Une carte peut etre attachee a 0 ou 1 member. Le solde / operations /
> passes sont realises par le plugin Cartes (E015). Ce service expose juste
> la lecture / lookup pour le POSClient et SalesService.AttachCard.
> 

### Services

#### `CardService`

CardService - lecture des cartes physiques / virtuelles. Appele par : POSClient (scan / saisie carte), SalesService.AttachCard en interne, MemberService (lister cartes d'un member). Pas de mutation ici - emission, recharge, blocage passent par ServerAdmin + plugin Cartes (E015). Codes d'erreur : NOT_FOUND, INVALID_ARGUMENT, FAILED_PRECONDITION (carte LOST/REVOKED/EXPIRED selon contexte d'usage).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetCard` | `GetCardRequest` | `Card` | - |
| `ListCards` | `ListCardsRequest` | `ListCardsResponse` | - |

### Messages

- `Card`
- `GetCardRequest`
- `ListCardsRequest`
- `ListCardsResponse`

### Enums

- `CardKind`
- `CardStatus`

---

## catalog

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/catalog.proto`

> E005-S03 - CatalogService : produits, categories, taxes.
> 
> Lecture seule depuis POSClient. La modification du catalogue passe par
> ServerAdmin (E007), pas par ce service. Les donnees sont synchronisees
> depuis ServerDB vers SQLite local du poste (Bootstrap data + delta sync).
> 

### Services

#### `CatalogService`

----- Service ----- CatalogService - lecture seule du catalogue produits / categories / taxes. Appele par : POSClient (recherche produit, autocomplete, scan barcode), et indirectement par SalesService.AddItem (resolution interne). Ne fait jamais d'ecriture - les modifications passent par ServerAdmin (E007) qui ecrit dans ServerDB (Postgres) et la sync se propage aux postes via Communication.Lib (bootstrap + delta). Erreurs typiques : NOT_FOUND si produit / categorie / tax inexistant ; INVALID_ARGUMENT si requete vide ou parametres incoherents.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetProductBySku` | `GetProductRequest` | `Product` | - |
| `GetProductByBarcode` | `GetProductByBarcodeRequest` | `Product` | - |
| `GetItem` | `GetItemRequest` | `Product` | - |
| `GetItems` | `GetItemsRequest` | `GetItemsResponse` | - |
| `SearchProducts` | `SearchProductsRequest` | `SearchProductsResponse` | - |
| `Autocomplete` | `AutocompleteRequest` | `AutocompleteResponse` | - |
| `ListCategories` | `ListCategoriesRequest` | `ListCategoriesResponse` | - |
| `GetActiveTaxes` | `GetTaxesRequest` | `GetTaxesResponse` | - |
| `ListPriceTierLists` | `ListPriceTierListsRequest` | `ListPriceTierListsResponse` | - |
| `ListPriceTierEntries` | `ListPriceTierEntriesRequest` | `ListPriceTierEntriesResponse` | - |
| `GetMedia` | `GetMediaRequest` | `MediaResponse` | - |

### Messages

- `AutocompleteHit`
- `AutocompleteRequest`
- `AutocompleteResponse`
- `Category`
- `GetItemRequest`
- `GetItemsRequest`
- `GetItemsResponse`
- `GetMediaRequest`
- `GetProductByBarcodeRequest`
- `GetProductRequest`
- `GetTaxesRequest`
- `GetTaxesResponse`
- `ListCategoriesRequest`
- `ListCategoriesResponse`
- `ListPriceTierEntriesRequest`
- `ListPriceTierEntriesResponse`
- `ListPriceTierListsRequest`
- `ListPriceTierListsResponse`
- `MediaResponse`
- `PriceOption`
- `PriceTierEntry`
- `PriceTierEntryWindow`
- `PriceTierList`
- `Product`
- `ProductCustomFieldValue`
- `SearchProductsRequest`
- `SearchProductsResponse`
- `Tax`

### Enums

- `PricingKind`

---

## common

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/common.proto`

> E005-S01 - Types fondamentaux partages par tous les services StillDeep.
> 
> Ces messages sont importes par tous les autres .proto. Ils definissent les
> conventions numeriques (R14 : aucun double / float, decimal partout) et les
> briques d'enveloppe : Money, Identifier, Pagination, ErrorDetail,
> PluginExtensions, etc.
> 
> R14 : montants en cents int64 (jamais double/float).
> Versioning : namespace stilldeep.v1.* - v2 sera un namespace separe.
> Convention : snake_case pour les fields, PascalCase pour les messages.
> 

### Messages

- `ActionResponse`
- `CustomFieldValue`
- `ErrorDetail`
- `Identifier`
- `Money`
- `PageInfo`
- `Pagination`
- `Percentage`
- `PluginExtensions`
- `Quantity`

---

## config

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/config.proto`

> E005-S14 - ConfigService : configuration runtime du poste + diagnostics.
> 
> Permet au caissier / manager de :
>   * lire la config courante (printer assignee, idle_timeout, branding).
>   * modifier les preferences user (language persist, theme).
>   * recuperer les logs recents pour debug (limite a 1h).
>   * declencher un restart propre du POSClient (apres update plugin).
> 
> La modification de la config commerce-wide (ex : tax_rates, business_hours)
> passe par ServerAdmin (E007), pas par ce service.
> 

### Services

#### `ConfigService`

ConfigService - configuration runtime + diagnostics. Codes d'erreur : NOT_FOUND, PERMISSION_DENIED, FAILED_PRECONDITION (restart avec paniers ouverts).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetPostConfig` | `GetPostConfigRequest` | `PostConfig` | - |
| `GetUserPreferences` | `GetUserPreferencesRequest` | `UserPreferences` | - |
| `UpdateUserPreferences` | `UpdateUserPreferencesRequest` | `UserPreferences` | - |
| `GetClientLogs` | `GetClientLogsRequest` | `GetClientLogsResponse` | - |
| `RestartClient` | `RestartClientRequest` | `RestartClientResponse` | - |

### Messages

- `GetClientLogsRequest`
- `GetClientLogsResponse`
- `GetPostConfigRequest`
- `GetUserPreferencesRequest`
- `LogEntry`
- `PaymentMethodInfo`
- `PostConfig`
- `RestartClientRequest`
- `RestartClientResponse`
- `StoreInfo`
- `UpdateUserPreferencesRequest`
- `UserHotkey`
- `UserPreferences`

### Enums

- `LogLevel`

---

## device

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/device.proto`

> E005-S05 - DeviceService : etat / controle des peripheriques POS.
> 
> Implementations concretes via plugins drivers (E011) - Epson ESC/POS,
> Moneris P2PE, etc. Ce service expose un controle uniforme cote UI.
> 

### Services

#### `DeviceService`

----- Service ----- DeviceService - controle / lecture des peripheriques POS. Appele par : POSClient (status pour iconographie UI, ouverture tiroir manuelle, test peripheriques en config), SalesService (impression auto au Finalize via ReceiptService -> DeviceService). Implementations : routees vers les plugins drivers via la chain IDeviceChain dans Intelligence.Lib. Chaque DeviceType a son driver specifique. Codes d'erreur : NOT_FOUND (device_id), FAILED_PRECONDITION (device pas READY), UNAVAILABLE (plugin driver absent), PERMISSION_DENIED. Dependances : EventService (publication DeviceStatusChangedEvent, DrawerOpenedEvent, ReceiptPrintedEvent).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListDevices` | `ListDevicesRequest` | `ListDevicesResponse` | - |
| `GetDeviceStatus` | `GetDeviceStatusRequest` | `GetDeviceStatusResponse` | - |
| `OpenCashDrawer` | `OpenCashDrawerRequest` | `ActionResponse` | - |
| `PrintReceipt` | `PrintReceiptRequest` | `ActionResponse` | - |
| `TestDevice` | `TestDeviceRequest` | `TestResponse` | - |

### Messages

- `Device`
- `GetDeviceStatusRequest`
- `GetDeviceStatusResponse`
- `ListDevicesRequest`
- `ListDevicesResponse`
- `OpenCashDrawerRequest`
- `PrintReceiptRequest`
- `TestDeviceRequest`
- `TestResponse`

### Enums

- `DeviceStatus`
- `DeviceType`

---

## events

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/events.proto`

> E005-S06 - EventService : streaming temps reel cote POSClient.
> 
> Permet a plusieurs UIs simultanees (caisse, customer display, kitchen
> display, second ecran) de voir le meme panier en direct. Le UI souscrit
> via Subscribe -> stream Event ; le serveur push toute mutation pertinente.
> 
> Note : le bus interne aux plugins (in-process AssemblyLoadContext) est une
> abstraction C# distincte (IPluginEventBus) - cf
> StillDeep.Intelligence.Plugins.Abstractions. Ce service gRPC ne dessert que
> les CLIENTS UI distants ou multi-poste.
> 

### Services

#### `EventService`

----- Service ----- EventService - flux temps reel pour synchronisation multi-UI. Appele par : POSClient principal (caisse), customer display, kitchen display, second ecran admin, plugins out-of-process. Patterns d'usage :   * Customer display : Subscribe(kinds=[CART, PAYMENT], cart_id_filter=<actif>)     -> affiche items + total en live.   * Kitchen display : Subscribe(kinds=[CART], post_id_filter=<resto>) ->     filtre cote client les Cart avec product_kind="restaurant_item".   * Scanner externe : Publish(ScanReceivedEvent) - le systeme route au     consommateur qui avait emis ScanRequestedEvent. Codes d'erreur : INVALID_ARGUMENT (subscriber_id vide), UNAUTHENTICATED.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `Subscribe` | `SubscribeRequest` | `Event` | server |
| `Publish` | `PublishEventRequest` | `ActionResponse` | - |
| `Heartbeat` | `HeartbeatRequest` | `HeartbeatResponse` | bidi |

### Messages

- `BalanceUpdatedEvent`
- `CartCardAttachedEvent`
- `CartItemAddedEvent`
- `CartItemRemovedEvent`
- `CartLocationAttachedEvent`
- `CartMemberAttachedEvent`
- `CartUpdatedEvent`
- `DeviceStatusChangedEvent`
- `DrawerOpenedEvent`
- `Event`
- `HeartbeatRequest`
- `HeartbeatResponse`
- `PaymentCompletedEvent`
- `PaymentInitiatedEvent`
- `PaymentMethodChangedEvent`
- `PublishEventRequest`
- `ReceiptPrintedEvent`
- `RefundIssuedEvent`
- `ScanReceivedEvent`
- `ScanRequestedEvent`
- `ShiftClosedEvent`
- `ShiftOpenedEvent`
- `ShiftPausedEvent`
- `ShiftResumedEvent`
- `SubscribeRequest`
- `TransactionFinalizedEvent`

### Enums

- `EventKindFilter`

---

## extensions

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/extensions.proto`

> E030 S14 - Documents d'extensions et sections des ecrans generiques.
> 
> Un document est une fiche d'extension sans table (un animal, une race, le reglage d'un
> produit) : valeurs en objet JSON validees par le schema de son type. Un poste lit tous les
> types ; il n'ecrit que ce que le type lui ouvre (post_access) et, si le type l'exige,
> avec la permission de l'employe du quart ouvert (post_permission).
> 

### Services

#### `DocumentService`

DocumentService - extension documents at a post. Writes run as the employee of the post's open shift. Errors: NOT_FOUND, PERMISSION_DENIED (type closed to posts, permission missing), FAILED_PRECONDITION (invalid values, no open shift, still referenced), with the reason code in the x-failure-code trailer.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetDocument` | `GetDocumentRequest` | `DocumentResponse` | - |
| `ListDocuments` | `ListDocumentsRequest` | `ListDocumentsResponse` | - |
| `SaveDocument` | `SaveDocumentRequest` | `DocumentResponse` | - |
| `ChangeDocument` | `ChangeDocumentRequest` | `DocumentResponse` | - |

#### `UiExtensionService`

UiExtensionService - sections declared by the extensions loaded on this post.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListUiExtensions` | `ListUiExtensionsRequest` | `ListUiExtensionsResponse` | - |

### Messages

- `ChangeDocumentRequest`
- `Document`
- `DocumentResponse`
- `GetDocumentRequest`
- `ListDocumentsRequest`
- `ListDocumentsResponse`
- `ListUiExtensionsRequest`
- `ListUiExtensionsResponse`
- `SaveDocumentRequest`
- `UiSection`

### Enums

- `DocumentAction`
- `DocumentPostAccess`
- `UiSectionKind`

---

## inventory

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/inventory.proto`

> E005-S11 - InventoryService : reception, transferts, ajustements, comptage,
> historique mouvements. Le stock disponible est calcule en sommation des
> product_inventory_movement (+/-). Aucun "compteur denormalise" — convention
> StillDeep, voir feedback_inventory_ledger memory.
> 
> Lecture du stock courant : Product.stock_quantity (CatalogService) calcule
> par le serveur a la demande. Pour un detail des mouvements, GetStockHistory.
> 
> Appele par : ServerAdmin (reception, transfert, ajustement), POSClient
> (count en magasin, restock manuel), plugins (consommation auto via recettes
> product_component).
> 

### Services

#### `InventoryService`

InventoryService - gestion de l'inventaire (ledger append-only). Codes d'erreur : INVALID_ARGUMENT (quantite negative pour Receive, kind invalide), NOT_FOUND, FAILED_PRECONDITION (stock insuffisant pour transfer si oversell_policy=block), PERMISSION_DENIED. Dependances : EventService publie StockMovementRecorded (a ajouter dans events.proto V2 si besoin live).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ReceiveStock` | `ReceiveStockRequest` | `ReceiveStockResponse` | - |
| `TransferStock` | `TransferStockRequest` | `TransferStockResponse` | - |
| `AdjustStock` | `AdjustStockRequest` | `AdjustStockResponse` | - |
| `CountInventory` | `CountInventoryRequest` | `CountInventoryResponse` | - |
| `GetStockLevel` | `GetStockLevelRequest` | `StockLevel` | - |
| `ListStockLevels` | `ListStockLevelsRequest` | `ListStockLevelsResponse` | - |
| `GetStockHistory` | `GetStockHistoryRequest` | `GetStockHistoryResponse` | - |

### Messages

- `AdjustStockRequest`
- `AdjustStockResponse`
- `CountInventoryRequest`
- `CountInventoryResponse`
- `GetStockHistoryRequest`
- `GetStockHistoryResponse`
- `GetStockLevelRequest`
- `ListStockLevelsRequest`
- `ListStockLevelsResponse`
- `ReceiveStockRequest`
- `ReceiveStockResponse`
- `StockLevel`
- `StockMovement`
- `TransferStockRequest`
- `TransferStockResponse`

### Enums

- `InventoryMovementKind`

---

## language

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/language.proto`

> E027 - LanguageService : selection + resolution de langue d'affichage.
> 
> Permet au caissier / kiosque / client de :
>   * Lister les langues actives (system_language is_active=true).
>   * Resoudre la langue effective pour un contexte (poste, employe, client).
>   * Forcer ponctuellement une langue sur un cart_id (override volatil).
>   * Effacer l'override volatil.
> 
> L'override est stocke en memoire dans Intelligence.Service (perdu au restart) —
> c'est intentionnel (cf. CLAUDE.md E027). Pour changer durablement la langue
> d'un poste ou d'un employe, passer par Server.Admin (E007).
> 

### Services

#### `LanguageService`

----- Service ----- Codes d'erreur :   * NOT_FOUND : locale demandee absente ou inactive dans system_language.   * INVALID_ARGUMENT : cart_id mal forme.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListLanguages` | `ListLanguagesRequest` | `ListLanguagesResponse` | - |
| `GetEffectiveLocale` | `GetEffectiveLocaleRequest` | `GetEffectiveLocaleResponse` | - |
| `SetCartLocaleOverride` | `SetCartLocaleOverrideRequest` | `SetCartLocaleOverrideResponse` | - |
| `ClearCartLocaleOverride` | `ClearCartLocaleOverrideRequest` | `ClearCartLocaleOverrideResponse` | - |

### Messages

- `ClearCartLocaleOverrideRequest`
- `ClearCartLocaleOverrideResponse`
- `GetEffectiveLocaleRequest`
- `GetEffectiveLocaleResponse`
- `Language`
- `ListLanguagesRequest`
- `ListLanguagesResponse`
- `SetCartLocaleOverrideRequest`
- `SetCartLocaleOverrideResponse`

---

## member

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/member.proto`

> E005-S04 - MemberService : recherche / lecture / creation / mise a jour
> des members (clients enregistres dans le programme).
> 
> Note : wallets / passes / programmes fidelite vivent dans le plugin Cartes
> (E015). GetWalletBalance retourne plugin_loaded=false si absent. Pour
> scanner / attacher une carte au panier, utiliser SalesService.AttachCard.
> 

### Services

#### `MemberService`

----- Service ----- MemberService - gestion des members (clients enrolles). Appele par : POSClient (recherche / creation rapide / association panier), ServerAdmin (CRUD complet). Codes d'erreur : NOT_FOUND, INVALID_ARGUMENT, ALREADY_EXISTS, PERMISSION_DENIED (status BARRED sans manager role), FAILED_PRECONDITION. Dependances : plugin Cartes pour GetWalletBalance.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetMemberByNumber` | `GetMemberRequest` | `Member` | - |
| `SearchMembers` | `SearchMembersRequest` | `SearchMembersResponse` | - |
| `CreateMember` | `CreateMemberRequest` | `Member` | - |
| `UpdateMember` | `UpdateMemberRequest` | `Member` | - |
| `ValidateMembership` | `ValidateMembershipRequest` | `ValidateMembershipResponse` | - |
| `GetWalletBalance` | `GetWalletBalanceRequest` | `GetWalletBalanceResponse` | - |
| `AssignCard` | `AssignCardRequest` | `MemberCard` | - |

### Messages

- `AssignCardRequest`
- `CommunicationPreferences`
- `CreateMemberRequest`
- `GetMemberRequest`
- `GetWalletBalanceRequest`
- `GetWalletBalanceResponse`
- `Member`
- `MemberAddress`
- `MemberCard`
- `Membership`
- `MemberStats`
- `SearchMembersRequest`
- `SearchMembersResponse`
- `UpdateMemberRequest`
- `ValidateMembershipRequest`
- `ValidateMembershipResponse`
- `WalletBalance`

### Enums

- `CommunicationChannel`
- `MemberStatus`

---

## pos_proxy

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/pos_proxy.proto`

> E025-S01 - Contrat gRPC du proxy DB POSCommunicationSvc <-> Server.Service.
> 
> Tous les acces BD depuis les postes passent par ce stream bidi long-lived
> chiffre (4 piliers crypto D19 : mTLS + ML-DSA + ML-KEM + PSK).
> Apres handshake, le poste envoie des ExecuteRequest avec un oneof typee
> par operation metier (D14 plan B retenu apres spike S00).
> 
> Aucune evaluation d'expression arbitraire cote serveur. Surface d'attaque
> applicative definie par les variants du oneof, executes par des handlers
> typed sous identite Postgres pos_user (D13 - vraie frontiere securite).
> 
> Versioning : namespace stilldeep.proxy.v1.* - v2 sera un namespace separe.
> 

### Services

#### `POSProxy`

=========================================================================== Service principal - stream bidi long-lived chiffre ===========================================================================

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `Connect` | `ClientEnvelope` | `ServerEnvelope` | bidi |

### Messages

- `AuthenticateUserOp`
- `BootstrapData`
- `BootstrapRequest`
- `CancelReservationOp`
- `ChangeDocumentOp`
- `ChangedResource`
- `ChangePasswordOp`
- `ChatAskAiOp`
- `ChatCancelAiOp`
- `ChatGetHistoryOp`
- `ChatGoOfflineOp`
- `ChatGoOnlineOp`
- `ChatListContactsOp`
- `ChatPushCmd`
- `ChatSendOp`
- `ClientEnvelope`
- `CloseShiftOp`
- `CommandAck`
- `CommandPush`
- `ConfirmMemberEmailOp`
- `CreateAppointmentOp`
- `CreateRentalOp`
- `DebitCardOp`
- `DeleteSavedCartOp`
- `DescribeDocumentsOp`
- `Error`
- `ExecuteRequest`
- `ExecuteResponse`
- `ExtensionDirective`
- `ExtensionPackageChunk`
- `ForceLogoffCmd`
- `GetCatalogOp`
- `GetCouponOp`
- `GetDiscountsOp`
- `GetDocumentOp`
- `GetEventSchedulesOp`
- `GetEventTicketTypesOp`
- `GetExtensionPackageOp`
- `GetMediaOp`
- `GetMemberAccountOp`
- `GetMemberByIdOp`
- `GetMemberCardsOp`
- `GetMemberProfileOp`
- `GetPaymentMethodsOp`
- `GetPostInfoOp`
- `GetPrintDocumentsOp`
- `GetProductOp`
- `GetSavedCartOp`
- `GetServiceAvailabilityOp`
- `GetSettingsOp`
- `GetShiftOp`
- `GetShiftSummaryOp`
- `GetStockLevelsOp`
- `GetTaxesOp`
- `GetTransactionOp`
- `GetUserAccessOp`
- `Handshake`
- `HandshakeAck`
- `HoldCartResourcesOp`
- `InsertAuditLogOp`
- `InsertFieldMesureOp`
- `InsertFieldTextOp`
- `InsertInventoryMovementOp`
- `InvalidateCatalogCacheCmd`
- `IssueCardOp`
- `IssueCouponsOp`
- `ListAccountDocumentsOp`
- `ListAppointmentsOp`
- `ListCategoriesOp`
- `ListDocumentsOp`
- `ListEventsOp`
- `ListOccupiedLocationsOp`
- `ListPostInputDevicesOp`
- `ListPostPrintersOp`
- `ListPostUsersOp`
- `ListRentalsOp`
- `ListSavedCartsOp`
- `ListSeatLocationsOp`
- `ListShiftsOp`
- `LockInventoryOp`
- `MediaResult`
- `OpenShiftOp`
- `PauseShiftOp`
- `Ping`
- `Pong`
- `PostExtension`
- `ReadAvailabilityOp`
- `RechargeCardOp`
- `RecordCloseDepositOp`
- `RecordTaskRunOp`
- `RefundTransactionOp`
- `RegisterMemberAccountOp`
- `ReleaseReservationOp`
- `RequestMemberPasswordResetOp`
- `ResetMemberPasswordOp`
- `ResourcesChangedCmd`
- `ResumeReservationOp`
- `ResumeShiftOp`
- `ReturnRentalOp`
- `SaveAccountDocumentOp`
- `SaveCartOp`
- `SaveDocumentOp`
- `SavePostInputDevicesOp`
- `SavePostPrintBindingOp`
- `SchemaRecoveryData`
- `SchemaRecoveryRequest`
- `SearchMembersOp`
- `SearchProductsOp`
- `SearchTransactionsOp`
- `ServerEnvelope`
- `SignInMemberOp`
- `SignOutMemberOp`
- `SubmitTransactionOp`
- `SyncExtensionsOp`
- `SyncExtensionsResult`
- `SyncOfflineKeysOp`
- `SyncOfflineKeysResult`
- `UnlockInventoryOp`
- `UpdateAppointmentOp`
- `UpdatePostHeartbeatOp`
- `UpdatePostVersionOp`
- `UpdateReservationOp`
- `UpsertMemberOp`
- `VoidTransactionOp`
- `WrappedOfflineKey`

### Enums

- `ErrorCode`
- `ExecuteStatus`
- `ExtensionAction`
- `OfflineKeyStatus`

---

## receipt

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/receipt.proto`

> ReceiptService - delivrer / reimprimer / renvoyer un recu.
> 
> Tout le rendu (PDF / ESC-POS / HTML email) est fait cote POSIntelligenceSvc.
> Le POSClient ne fait que demander : pour la transaction X, format Y, canal Z.
> L'Intelligence se charge de :
>   - rendre le contenu (i18n, taxes detaillees, branding)
>   - envoyer au peripherique (imprimante via DeviceService E011)
>   - poster dans une queue email/SMS pour les canaux differes
> 
> Cette separation permet aux POSClient open-source (Web, Mobile, Kiosque
> fork) de ne pas reimplementer le templating + drivers d'imprimante.
> 

### Services

#### `ReceiptService`

ReceiptService - emission et recherche de recus. Appele par : POSClient (apres Finalize si pas auto-emis, ecran reimpression, envoi email apres-coup), Kiosk (recu cadeau). Implementation : routee vers le pipeline de rendu interne (templates) + DeviceService (imprimante) + plugin SMTP/SMS pour les canaux differes. Codes d'erreur : NOT_FOUND (transaction), INVALID_ARGUMENT (destination manquante pour EMAIL/SMS), FAILED_PRECONDITION (imprimante pas READY), UNAVAILABLE (plugin SMTP/SMS manquant). Dependances : Transaction (SalesService), Member (CommunicationPreferences), Device (impression), EventService (publication ReceiptPrintedEvent).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `EmitReceipt` | `EmitReceiptRequest` | `ReceiptRenderResult` | - |
| `FindReceipts` | `FindReceiptsRequest` | `FindReceiptsResponse` | - |

### Messages

- `EmitReceiptRequest`
- `FindReceiptsRequest`
- `FindReceiptsResponse`
- `ReceiptRenderResult`
- `ReceiptSummary`

### Enums

- `ReceiptChannel`
- `ReceiptFormat`

---

## rental

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/rental.proto`

> RentalService : contrats de location d'articles (sortie, echeance, retour, depot).
> 
> Une location vendue au comptoir s'ouvre a la finalisation (SalesService.AddItem avec
> rental_due_at). CreateRental ouvre un contrat hors vente (reservation a venir, pret).
> 

### Services

#### `RentalService`

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListRentals` | `ListRentalsRequest` | `ListRentalsResponse` | - |
| `CreateRental` | `CreateRentalRequest` | `RentalResponse` | - |
| `ReturnRental` | `ReturnRentalRequest` | `RentalResponse` | - |

### Messages

- `CreateRentalRequest`
- `ListRentalsRequest`
- `ListRentalsResponse`
- `Rental`
- `RentalResponse`
- `ReturnRentalRequest`

### Enums

- `RentalScope`

---

## report

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/report.proto`

> E005-S12 - ReportService : rapports operationnels in-POS.
> 
> Pour les rapports analytiques avances (BI, dashboards complexes), utiliser
> ServerReport (E008) qui consomme directement la BD. Ce service expose juste
> les donnees temps-reel necessaires au caissier / manager pendant un quart.
> 
> Aucune mutation - read-only pure. Permissions : `report.shift_summary` /
> `report.top_products` / `report.cashier_productivity` (manager).
> 

### Services

#### `ReportService`

ReportService - rapports temps-reel pour le caissier / manager. Codes d'erreur : NOT_FOUND, PERMISSION_DENIED.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetShiftSummary` | `GetShiftSummaryRequest` | `ShiftSummary` | - |
| `GetTopProducts` | `GetTopProductsRequest` | `GetTopProductsResponse` | - |
| `GetSalesByMethod` | `GetSalesByMethodRequest` | `GetSalesByMethodResponse` | - |
| `GetTipSummary` | `GetTipSummaryRequest` | `TipSummary` | - |
| `GetCashierProductivity` | `GetCashierProductivityRequest` | `GetCashierProductivityResponse` | - |

### Messages

- `CashierProductivityEntry`
- `CashierTipEntry`
- `GetCashierProductivityRequest`
- `GetCashierProductivityResponse`
- `GetSalesByMethodRequest`
- `GetSalesByMethodResponse`
- `GetShiftSummaryRequest`
- `GetTipSummaryRequest`
- `GetTopProductsRequest`
- `GetTopProductsResponse`
- `PaymentMethodSummary`
- `ProductSalesEntry`
- `ShiftSummary`
- `TipSummary`

---

## sales

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/sales.proto`

> E005-S02 - SalesService : panier, paiement, finalisation.
> 
> Service principal expose par POSIntelligenceSvc, consomme par tous les
> POSClient (Reference Windows, web, kiosque, mobile). C'est le coeur du
> flux vente : creation de panier -> ajout / retrait de lignes -> rabais ->
> paiement -> finalisation -> recu.
> 
> Idempotency : toute mutation expose un idempotency_key. Re-emission avec
> la meme cle => meme reponse, sans effet de bord. Le serveur conserve les
> cles 24h cote SQLite local.
> 

### Services

#### `SalesService`

----- Service ----- SalesService - service principal du POS. Toutes les operations de panier, paiement et finalisation passent ici. Appele par : POSClient (Reference Windows, web, kiosque, mobile) en gRPC sur localhost (pipe HTTP/2). Aucun appel externe au LAN du client. Pre-conditions communes : un shift OPEN doit exister sur le poste pour le cashier_user_id. Sinon PERMISSION_DENIED. Les permissions par RPC sont checkees via interceptor (voir ShiftService.CheckPermission pour pre-check UI). Codes d'erreur principaux :   INVALID_ARGUMENT     - parametres incoherents (ex : product_id et sku tous deux vides).   NOT_FOUND            - cart / produit / member / transaction inexistant.   FAILED_PRECONDITION  - cart status incompatible (ex : Finalize sur cart VOIDED).   PERMISSION_DENIED    - pas de shift open, ou role insuffisant pour discount/refund.   UNAUTHENTICATED      - manager_auth_token invalide ou expire.   ALREADY_EXISTS       - re-emission detecte par idempotency_key, retour idempotent. Patterns d'usage (extraits) :   * Vente cash standard : CreateCart -> AddItem* -> ProcessPayment(cash) ->     FinalizeTransaction.   * Split payment : CreateCart -> AddItem* -> ProcessPayment(card_p2pe partial)     -> ProcessPayment(cash for rest) -> FinalizeTransaction.   * Refus carte avec fallback : ProcessPayment(card) -> refus -> ResolvePaymentRefusal     (FALLBACK_TO_CASH) -> ProcessPayment(cash) -> FinalizeTransaction.   * Pause / reprise : SaveCart -> [client occupe autre cart] -> GetSavedCart -> ...   * Reservation : AddItem* -> AssociateMember (or a rented location) -> ProcessPayment (deposit, optional)     -> ReserveCart ; later ResumeReservation -> AddItem (fees) -> ProcessPayment -> ReserveCart or     FinalizeTransaction ; or PreviewReservationCancellation -> CancelReservation(expected_refund). Dependances : CatalogService (resolution produit dans AddItem), MemberService (AssociateMember), CardService (AttachCard), DeviceService (impression via FinalizeTransaction), EventService (publication evenements panier).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `CreateCart` | `CreateCartRequest` | `CartResponse` | - |
| `GetCart` | `GetCartRequest` | `CartResponse` | - |
| `AddItem` | `AddItemRequest` | `CartResponse` | - |
| `RemoveLine` | `RemoveLineRequest` | `CartResponse` | - |
| `UpdateQuantity` | `UpdateQuantityRequest` | `CartResponse` | - |
| `UpdateLineNote` | `UpdateLineNoteRequest` | `CartResponse` | - |
| `ListDiscounts` | `ListDiscountsRequest` | `ListDiscountsResponse` | - |
| `ApplyDiscount` | `ApplyDiscountRequest` | `CartResponse` | - |
| `RemoveDiscount` | `RemoveDiscountRequest` | `CartResponse` | - |
| `AssociateMember` | `AssociateMemberRequest` | `CartResponse` | - |
| `AttachCard` | `AttachCardRequest` | `CartResponse` | - |
| `DetachCard` | `DetachCardRequest` | `CartResponse` | - |
| `AttachLocation` | `AttachLocationRequest` | `CartResponse` | - |
| `DetachLocation` | `DetachLocationRequest` | `CartResponse` | - |
| `BeginPayment` | `BeginPaymentRequest` | `CartResponse` | - |
| `ResolveInteraction` | `ResolveInteractionRequest` | `CartResponse` | - |
| `SetLineMember` | `SetLineMemberRequest` | `CartResponse` | - |
| `SetSubject` | `SetSubjectRequest` | `CartResponse` | - |
| `SetExtensions` | `SetExtensionsRequest` | `CartResponse` | - |
| `SelectPaymentMethod` | `SelectPaymentMethodRequest` | `CartResponse` | - |
| `CancelPayment` | `GetCartRequest` | `CartResponse` | - |
| `ProcessPayment` | `ProcessPaymentRequest` | `PaymentResponse` | - |
| `ResolvePaymentRefusal` | `ResolvePaymentRefusalRequest` | `PaymentResponse` | - |
| `ClearPayments` | `GetCartRequest` | `CartResponse` | - |
| `FinalizeTransaction` | `FinalizeRequest` | `TransactionResponse` | - |
| `CancelCart` | `GetCartRequest` | `ActionResponse` | - |
| `SendToKitchen` | `SendToKitchenRequest` | `ActionResponse` | - |
| `SaveCart` | `SaveCartRequest` | `SaveCartResponse` | - |
| `ListSavedCarts` | `ListSavedCartsRequest` | `ListSavedCartsResponse` | - |
| `GetSavedCart` | `GetSavedCartRequest` | `CartResponse` | - |
| `DeleteSavedCart` | `DeleteSavedCartRequest` | `ActionResponse` | - |
| `SearchTransactions` | `SearchTransactionsRequest` | `SearchTransactionsResponse` | - |
| `GetTransaction` | `GetTransactionRequest` | `TransactionResponse` | - |
| `RefundTransaction` | `RefundTransactionRequest` | `TransactionResponse` | - |
| `ReserveCart` | `ReserveCartRequest` | `ReserveCartResponse` | - |
| `ListReservations` | `ListReservationsRequest` | `ListReservationsResponse` | - |
| `ResumeReservation` | `ResumeReservationRequest` | `CartResponse` | - |
| `ReleaseReservation` | `ReleaseReservationRequest` | `ActionResponse` | - |
| `PreviewReservationCancellation` | `CancelReservationRequest` | `ReservationCancellationResponse` | - |
| `CancelReservation` | `CancelReservationRequest` | `ReservationCancellationResponse` | - |

### Messages

- `AddItemRequest`
- `AppliedDiscount`
- `AppliedTax`
- `ApplyDiscountRequest`
- `AssociateMemberRequest`
- `AttachCardRequest`
- `AttachLocationRequest`
- `BeginPaymentRequest`
- `CancelReservationRequest`
- `Cart`
- `CartLine`
- `CartReservation`
- `CartResponse`
- `CreateCartRequest`
- `DeleteSavedCartRequest`
- `DetachCardRequest`
- `DetachLocationRequest`
- `DiscountCatalogEntry`
- `FinalizeRequest`
- `GetCartRequest`
- `GetSavedCartRequest`
- `GetTransactionRequest`
- `Interaction`
- `InteractionChoice`
- `ListDiscountsRequest`
- `ListDiscountsResponse`
- `ListReservationsRequest`
- `ListReservationsResponse`
- `ListSavedCartsRequest`
- `ListSavedCartsResponse`
- `Notice`
- `Payment`
- `PaymentRefusalGuide`
- `PaymentResponse`
- `ProcessPaymentRequest`
- `RefundLineSelection`
- `RefundSeat`
- `RefundTransactionRequest`
- `ReleaseReservationRequest`
- `RemoveDiscountRequest`
- `RemoveLineRequest`
- `Reservation`
- `ReservationCancellationResponse`
- `ReservationKeptLine`
- `ReservationRefund`
- `ReserveCartRequest`
- `ReserveCartResponse`
- `ResolveInteractionRequest`
- `ResolvePaymentRefusalRequest`
- `ResumeReservationRequest`
- `SaveCartRequest`
- `SaveCartResponse`
- `SavedCart`
- `SearchTransactionsRequest`
- `SearchTransactionsResponse`
- `SelectPaymentMethodRequest`
- `SendToKitchenRequest`
- `SetExtensionsRequest`
- `SetLineMemberRequest`
- `SetSubjectRequest`
- `Transaction`
- `TransactionLine`
- `TransactionResponse`
- `TransactionSummary`
- `UpdateLineNoteRequest`
- `UpdateQuantityRequest`

### Enums

- `CartStatus`
- `DiscountKind`
- `DiscountSource`
- `DiscountTiming`
- `InteractionKind`
- `InteractionTargetKind`
- `NoticeLevel`
- `PaymentStatus`
- `RefusalAction`

---

## scheduling

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/scheduling.proto`

> SchedulingService: scheduled ticketing (cinema, theatre, conference).
> 
> ScheduledEvent ("Dune Part 3") -> EventSchedule (showing "Friday 7 pm, hall 4")
>                                -> EventTicketType ("Adult", "Student", "VIP").
> A seat is a seat location (product_location.location_kind = 'seat'); seat_id is its product id.
> The client draws the hall itself.
> 

### Services

#### `SchedulingService`

----- Service ----- SchedulingService - scheduled ticketing: events, showings, ticket types, seats. Seats and capacities are the server's. HoldSeat holds a seat on the server for an open SalesService cart until expires_at (renewed while the cart lives), ReleaseSeat or a cancelled cart gives it back. Other posts' changes are not pushed: read GetSeatMap / GetSchedules again. SalesService.AddItem carries no showing nor seats yet: a held seat is not sold here. Errors: NOT_FOUND (cart_not_found, hold_not_found), FAILED_PRECONDITION (seat_taken, resource_invalid), INVALID_ARGUMENT.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListEvents` | `ListEventsRequest` | `ListEventsResponse` | - |
| `GetSchedules` | `GetSchedulesRequest` | `GetSchedulesResponse` | - |
| `GetTicketTypes` | `GetTicketTypesRequest` | `GetTicketTypesResponse` | - |
| `GetSeatMap` | `GetSeatMapRequest` | `GetSeatMapResponse` | - |
| `HoldSeat` | `HoldSeatRequest` | `HoldSeatResponse` | - |
| `ReleaseSeat` | `ReleaseSeatRequest` | `ActionResponse` | - |

### Messages

- `EventSchedule`
- `EventTicketType`
- `GetSchedulesRequest`
- `GetSchedulesResponse`
- `GetSeatMapRequest`
- `GetSeatMapResponse`
- `GetTicketTypesRequest`
- `GetTicketTypesResponse`
- `HoldSeatRequest`
- `HoldSeatResponse`
- `ListEventsRequest`
- `ListEventsResponse`
- `ReleaseSeatRequest`
- `ScheduledEvent`
- `Seat`

### Enums

- `SeatStatus`

---

## shift

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/shift.proto`

> ShiftService - cycle de vie d'un quart de travail.
> 
> Etats : open -> paused -> open -> ... -> closed -> reconciled.
> Invariants :
>   * 1 user = 1 shift open max (cross-poste). Tentative double-open = FAILED_PRECONDITION.
>   * 1 poste = 1 shift open max.
>   * Cashier-less posts (default_user_id + is_always_open or post_type.has_shift=false): the server opens
>     the shift on demand as default_user_id and rolls it at business_day_cutoff. The UI never calls Open/Close.
> 
> Fermeture : on declare un montant depose pour chaque payment_method dont
> deposit_at_close=true (cash typique). Si aucune vente -> close direct sans
> dialog (no-op deposit).
> 

### Services

#### `ShiftService`

ShiftService - gestion du quart de travail. Appele par : POSClient (open au login, close au logout), tous les services SalesService/Device/etc. via interceptor pour validation permissions, et UI pour pre-validation de boutons. Patterns d'usage :   * Login : UserService.Authenticate -> OpenShift.   * Pause repas : PauseShift -> ResumeShift.   * Fin de journee : CloseShift avec declared_deposits par methode. Codes d'erreur : NOT_FOUND, FAILED_PRECONDITION (deja open / not open), PERMISSION_DENIED, ALREADY_EXISTS (idempotency). Dependances : UserService (auth), publication ShiftOpenedEvent / ShiftPausedEvent / ShiftResumedEvent / ShiftClosedEvent via EventService.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `OpenShift` | `OpenShiftRequest` | `OpenShiftResponse` | - |
| `PauseShift` | `PauseShiftRequest` | `Shift` | - |
| `ResumeShift` | `ResumeShiftRequest` | `Shift` | - |
| `CloseShift` | `CloseShiftRequest` | `CloseShiftResponse` | - |
| `GetCurrentShift` | `GetCurrentShiftRequest` | `Shift` | - |
| `ListShifts` | `ListShiftsRequest` | `ListShiftsResponse` | - |
| `CheckPermission` | `CheckPermissionRequest` | `CheckPermissionResponse` | - |

### Messages

- `CheckPermissionRequest`
- `CheckPermissionResponse`
- `CloseShiftRequest`
- `CloseShiftResponse`
- `DeclaredDeposit`
- `GetCurrentShiftRequest`
- `ListShiftsRequest`
- `ListShiftsResponse`
- `OpenShiftRequest`
- `OpenShiftResponse`
- `PauseShiftRequest`
- `ResumeShiftRequest`
- `Shift`
- `ShiftDeposit`
- `ShiftPause`

### Enums

- `ShiftStatus`

---

## sync

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/sync.proto`

> E005-S13 - SyncService : synchronisation outbox + sante reseau du poste.
> 
> Le poste maintient une SQLite locale + une outbox des mutations. Quand
> la connexion vers ServerDB Postgres est restauree, le worker drain
> l'outbox. Ce service permet au UI de :
>   * voir l'etat de la sync (online/degraded/offline + outbox count)
>   * forcer un drain manuel (ex : caissier qui voit 200 messages en attente)
>   * monitorer la sante reseau (latence vers ServerDB)
> 

### Services

#### `SyncService`

SyncService - lecture / pilotage de la sync. Appele par : POSClient (indicateur connexion + bouton "Force resync"), ServerAdmin (vue dashboard postes en ligne). Codes d'erreur : PERMISSION_DENIED (force_drain), UNAVAILABLE (worker sync arrete - cas degenere).

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `GetSyncStatus` | `GetSyncStatusRequest` | `SyncStatus` | - |
| `GetOutboxCount` | `GetOutboxCountRequest` | `GetOutboxCountResponse` | - |
| `ForceDrain` | `ForceDrainRequest` | `ForceDrainResponse` | - |

### Messages

- `ForceDrainRequest`
- `ForceDrainResponse`
- `GetOutboxCountRequest`
- `GetOutboxCountResponse`
- `GetSyncStatusRequest`
- `SyncStatus`

### Enums

- `SyncState`

---

## user

Fichier source : `src/public/StillDeep.Intelligence.Contracts/protos/user.proto`

> UserService - authentification (mode password ou scan id) + lecture
> post auth modes acceptes + idle timeout.
> 
> Plugins (RFID, magstripe, scanner exotique) ne s'integrent PAS dans cet
> API : ils injectent localement un "barcode" ou "credential string" via
> l'event bus du POSClient (ScanReceivedEvent), et ce dernier appelle
> Authenticate avec le mode "barcode" + le credential. Le service ne sait
> pas d'ou vient le code - il sait juste qu'il a recu un identifier a
> resoudre.
> 

### Services

#### `UserService`

UserService - authentification et lookup users. Appele par : POSClient (login screen, dropdown selection user), tous les RPC qui acceptent un manager_auth_token (override discount, refund, etc.). Codes d'erreur : INVALID_ARGUMENT (mode non accepte par le poste, login vide), UNAUTHENTICATED (credentials invalides), PERMISSION_DENIED (user suspended/locked/deactivated), NOT_FOUND (post_id inconnu). Dependances : ServerDB pour stockage users (Postgres), publication ShiftOpenedEvent indirectement via OpenShift.

| RPC | Request | Response | Streaming |
|---|---|---|---|
| `ListUsersForPost` | `ListUsersForPostRequest` | `ListUsersForPostResponse` | - |
| `GetPostAuthConfig` | `GetPostAuthConfigRequest` | `PostAuthConfig` | - |
| `Authenticate` | `AuthenticateRequest` | `AuthenticateResponse` | - |
| `ResetPasswordEmail` | `ResetPasswordEmailRequest` | `ResetPasswordEmailResponse` | - |
| `ResetPasswordAutoGenerate` | `ResetPasswordAutoGenerateRequest` | `ResetPasswordAutoGenerateResponse` | - |
| `ChangePassword` | `ChangePasswordRequest` | `ChangePasswordResponse` | - |

### Messages

- `AuthenticateRequest`
- `AuthenticateResponse`
- `ChangePasswordRequest`
- `ChangePasswordResponse`
- `GetPostAuthConfigRequest`
- `ListUsersForPostRequest`
- `ListUsersForPostResponse`
- `PostAuthConfig`
- `ResetPasswordAutoGenerateRequest`
- `ResetPasswordAutoGenerateResponse`
- `ResetPasswordEmailRequest`
- `ResetPasswordEmailResponse`
- `UserSummary`

### Enums

- `AuthMode`

---

## Comment appeler

```bash
# Lister les services via reflection
grpcurl -plaintext localhost:50051 list

# Lister les RPCs d'un service
grpcurl -plaintext localhost:50051 list stilldeep.v1.CatalogService

# Decrire un message
grpcurl -plaintext localhost:50051 describe stilldeep.v1.Cart

# Appeler un RPC
grpcurl -plaintext -d '{"query":"kind:boutique"}' localhost:50051 stilldeep.v1.CatalogService/SearchProducts
```

## Endpoints REST associes

| URL | Description |
|---|---|
| `http://localhost:5050/healthz` | Healthcheck Docker (HTTP/1.1) |
| `http://localhost:5051/grpc-info` | Manifeste JSON dynamique des services + RPCs |
| `http://localhost:5051/swagger` | Swagger UI (description seule en V1, transcoding live attendra .NET 11 GA) |
| `http://localhost:5051/swagger/v1/swagger.json` | OpenAPI JSON minimal |

Source: https://stilldeeppos.com/fr/docs/reference/grpc
