12 KiB
System identity
Zeus is the .NET 8 multi-service platform powering the GrowingWay property-rental product.
Owner: Giuseppe. Area keys: backend, backoffice, infra.
Three deployable services:
zeus_auth— Auth, User, Policy, Devices, Settings gRPC APIs (hostauth.{DOMAIN})zeus_property— Announcement, Booking, Chat, Review, Notification gRPC APIs + SignalR payment and chat hubs (hostproperty.{DOMAIN})zeus_admin— Blazor Server backoffice dashboard (hostadmin.{DOMAIN})
Infrastructure: nginx edge (SNI/L4 passthrough on :443) → per-env nginx web (TLS termination, L7 host-header routing) → backend containers. Redis for SignalR session registries. PostgreSQL (remote, never touch locally). Google Cloud Storage for images. Stripe for payments. Ermes (external gRPC) for SMS.
User-visible surfaces
zeus_admin (backoffice) pages — URL : nav label : heading
/: Home : Panoramica — summary: host count, annunci count, media annunci/host/Users: Users — backoffice account management/support-levels: Livelli Supporto : Livelli di Supporto — RBAC for support operators/Policy: Policy — policy types and versions/amenities: Servizi : Gestione Servizi — amenity categories and types/tags: Announcement Tags : Gestione Tag Annunci/reviews: Recensioni : Recensioni — review parameters/Verifications: Verifiche Utenti : Richieste di Verifica — KYC queue (fronte/retro documento + selfie)/Hosts: Host : Host — host list/Hosts/{id}— host detail: Dati Personali, Stripe onboarding, announcements, bookings, availability block/Announcements/{id}— annuncio detail: Titolo, Descrizione, Meta Descrizione, Indirizzo/Bookings: Prenotazioni : Prenotazioni — columns: Stato, Pagamento, Guest, Host, Check-in, Check-out, Importo, Prossima cattura, Creata/Bookings/{id}: Prenotazione — sections: Dettagli prenotazione, Sessione di pagamento, Tentativi; actions: Cattura ora / Ripianifica / Force Accept / Force Reject / Force Cancel/Guests: Guest — guest user list/support/chats: Chat Supporto : Chat Supporto — columns: Nome, Cognome, ID Utente, Ultima attività/support/chats/{userId}— live support chat conversation/reports: Segnalazioni : Segnalazioni — chat-report moderation; columns: Segnalante, Segnalato, Motivo, Stato (Open / Reviewed / Dismissed)/support: Apri sessione di supporto / Sessione di supporto attiva — operator enters user's Codice Supporto; session becomes active after user acceptance/support/user: Utente Target — data view for active support-session user
zeus_property gRPC services (app-facing)
GuestAnnouncementService (browse/search listings), GuestBookingService (Book, RetryPayment, CancelBooking, GetSummary), GuestChatService (SendMessage, GetMessages, RequestSupportChat, ReportUser, BlockUser), GuestReviewService, GuestNotificationService (ListNotifications, MarkNotificationRead), GuestReceiptService, GuestFeedbackService, HostPropertyService (listing CRUD, image upload), HostBookingService (ConfirmReservation, ghost bookings), HostOnboardingService (Stripe Connect), HostReferralService.
SignalR hubs: /api/guest/payments (PaymentHub — BindSession → IssuePayment → Success/Failed callbacks), /api/guest/chat (ChatHub — real-time delivery).
zeus_auth gRPC services
AuthAuthenticationService (Register, Login, ConfirmPhoneNumber, Refresh, RecoverPassword, VerifyConfirmationCode), AuthUserService (profile, KYC upload + submit), AuthPolicyService (SubscribeToPolicy, streaming updates), AuthDevicesService, AuthSettingsService, AuthLogService (Flutter log ingest), PrivacyService (account deletion).
Error fingerprints
Errors surface as gRPC status codes (and mapped HTTP codes for transcoding). The Flutter app displays the localized message field from the gRPC Status detail.
Localized error strings (it-IT / en-US)
| Key | it-IT | en-US |
|---|---|---|
WRONG_PASSWORD |
"La password inserita non è corretta." | "The password you entered is incorrect." |
INVALID_CONFIRMATION_CODE |
"Il codice di verifica inserito è incorretto o scaduto." | "The verification code you entered is incorrect or has expired." |
SMS_SERVICE_UNAVAILABLE |
"Stiamo avendo problemi nell'invio degli SMS. Riprova più tardi." | "We're having trouble sending text messages right now. Please try again later." |
INVALID_ACCESS_TOKEN |
"La tua sessione è scaduta. Effettua nuovamente l'accesso." | "Your session has expired. Please log in again." |
ANNOUCEMENT_NOT_FOUND |
"Abbiamo riscontrato un errore nel recuperarti questo annuncio" | "We're having trouble getting this announcement." |
APARTMENT_UNAVAILABLE |
"Questo appartamento non è più disponibile." | "This apartment is no longer available." |
PRICE_CHANGED |
"Il prezzo per questo appartamento è cambiato." | "The price for this apartment has changed." |
PAYMENT_FAILED |
"Il pagamento non è andato a buon fine. Riprova." | "The payment was unsuccessful. Please try again." |
UNBOUND_PAYMENT_SESSION |
"Qualcosa è andato storto. Riprova più tardi." | "Something went wrong. Please try again later." |
TOO_MANY_CODE_REQUESTED |
"Sono stati richiesti troppi codici per questo numero di telefono oggi." | "Too many codes were requested for this phone number today." |
TERMS_NOT_ACCEPTED |
"Devi accettare i termini e le condizioni per continuare." | "You must accept the terms and conditions to continue." |
NO_HOST_DATA_FOUND |
"Configurazione host non trovata. Completa il processo di registrazione." | "Host configuration not found. Please complete the onboarding process." |
ANNOUNCEMENT_HAS_NO_IMAGES |
"Aggiungi almeno un'immagine a questo annuncio." | "Please add at least one image to this announcement." |
Admin-only (Zeus.Admin/errors.json):
| Key | it | en |
|---|---|---|
INVALID_SUPPORT_CODE |
"Il codice di supporto inserito non è valido" | "The support code is not valid" |
UNAUTHORIZED_SUPPORT_REQUEST |
"Questa richiesta non è ancora stata accettata" | "This request has not yet been accepted" |
gRPC status codes and infrastructure errors
| Scenario | gRPC status | Code |
|---|---|---|
| Backend container down / nginx upstream fail | Unavailable |
14 |
| DB unreachable (first call) | Internal |
13 |
| Unhandled exception | Internal |
13 |
| Auth failure / expired JWT | Unauthenticated |
16 |
| Validation errors | InvalidArgument |
3 |
| Rate limit (OTP flood / SMS flood) | ResourceExhausted |
8 |
| State-guard violations | FailedPrecondition |
9 |
| Stripe payment declined | Aborted |
10 |
Payment SignalR failure codes: Failed(code) where code is a Stripe string (card_declined, insufficient_funds, amount_mismatch) or a Zeus key (PAYMENT_FAILED, UNBOUND_PAYMENT_SESSION). These raw codes reach the Flutter app directly — they are NOT localized by the server.
TLS failure appears as CERTIFICATE_VERIFY_FAILED or HandshakeException in Flutter logs (not a Zeus error; see infra).
Symptom → area heuristics
- payment stuck / perpetually "processing" after booking confirmation →
backend(Stripe webhook not processed; checkStripeWebhookControllerlogs for signature failure) - "Il pagamento non è andato a buon fine" before card entry →
backend(PAYMENT_SESSION_CLOSEDorUNBOUND_PAYMENT_SESSION; admin may have force-cancelled the session) - payment
Failedcallback with Stripe code (card_declined,insufficient_funds) →backend(Stripe declined; retry flow in app is correct) - chat messages sent but other party never receives →
backend(checkSendMessagegRPC response + Redis chat registry;SetOnlinemay have expired) - OTP / SMS login code not arriving →
backend(Ermes SMS service; keySMS_SERVICE_UNAVAILABLE) - OTP code rejected as wrong or expired →
backend(INVALID_CONFIRMATION_CODE) - wrong or missing data shown in app with correct layout →
backend(data model or repository issue) - announcement detail missing, showing error toast →
backend(ANNOUCEMENT_NOT_FOUND) - booking dates show as unavailable despite being free →
backend(APARTMENT_UNAVAILABLE— availability row state) - "La tua sessione è scaduta" in the middle of a session (not at launch) →
backend(INVALID_ACCESS_TOKENreturned by server; JWT refresh failed) - host onboarding "Completa il processo di registrazione" on every login →
backend(NO_HOST_DATA_FOUND— HostData row missing) - notification badge count never resets →
backend(MarkNotificationReadfailing server-side, e.g. stale notification ID) - user cannot leave a review after a stay →
backend(reviews are only allowed once the booking reachesCompleted; check booking status) - admin dashboard page errors, wrong data in grids, action buttons fail →
backoffice - admin support code rejected ("Il codice di supporto inserito non è valido") →
backoffice - site / app entirely unreachable, no HTTP response at all →
infra(nginx.edge or docker stack down; TCP connection refused on :443/:80) - 502 from nginx, gRPC status 14 "Unavailable" →
infra(upstream container crash) - TLS certificate warning or
CERTIFICATE_VERIFY_FAILED→infra(Let's Encrypt cert expired or nginx misconfigured) - visual glitches, overflow stripes, layout overflow, misaligned widgets →
app-shared(Flutter rendering; not Zeus) - platform-specific crash on Android or iOS (no network call) →
app-android/app-ios
Domain glossary
| Italian term | System concept |
|---|---|
| Annuncio / Annunci | Announcement entity; listing published by a host |
| Host | A user who completed Stripe onboarding; can publish annunci |
| Ospite / Guest | A user making a booking |
| Prenotazione / Prenotazioni | BookingOrder entity |
| Check-in / Check-out | Arrival and departure dates on a booking |
| Sessione di pagamento | PaymentSession — Stripe PaymentIntent/SetupIntent lifecycle; statuses: Ongoing, AwaitingCapture, Succeeded, Failed, Cancelled |
| Segnalazione / Segnalazioni | ChatReport — chat moderation report; statuses: Open, Reviewed, Dismissed |
| Verifica / Verifiche Utenti | VerificationRequest — KYC identity check; statuses: Draft, Pending, Approved, Rejected |
| Recensione / Recensioni | AnnouncementReview — post-stay review; only possible after booking Completed |
| Servizi | Amenities (wifi, parking, …); GuestAmenityService |
| Notifica | In-app notification; GuestNotificationService |
| Codice Supporto | Short-lived code user reads aloud to operator to start a support session |
| Sessione di supporto | Admin operator impersonation session for support |
| Livelli di Supporto | RBAC levels for admin operators |
| Codice invito | Referral code; HostReferralService |
| Cattura / Cattura ora | Stripe delayed capture; admin action on booking detail |
| Panoramica | Admin dashboard home |
Not mine
- Visual rendering artifacts, overflow widgets, clipped text, wrong font size →
app-shared - "Sessione scaduta" toast at app launch with no network request in logs →
app-shared(Flutter JWT expiry check done locally — no server call) - Search map shows no results despite listings existing (no gRPC error) →
app-shared(Flutter map range / filter state) - Chat messages in wrong order or duplicated →
app-shared(Flutter merge of historical stream + SignalR without dedup) - Announcement images load as blank (HTTP 200 from GCS) →
app-shared(Flutter image widget render failure; HTTP 403 = expired GCS URL =backend) - Host calendar shows wrong blocked dates after refresh →
app-shared(stale local cache; re-callingGetReservationsreturns correct data) - Android-specific crash, iOS-specific crash →
app-android/app-ios - Store deployment failures, app binary issues →
app-android/app-ios - Push notification delivery on device (FCM/APNs) →
app-shared(not Zeus; Zeus only stores tokens viaAuthDevicesService)