Skip to content

docs product NOTIFICATION_CONTENT_CONTRACT

AlexandreZanata edited this page Oct 13, 2026 · 1 revision

Notification content and OneSignal delivery contract

State: PLANNED / CONTENT PROPOSAL ONLY, 2026-10-13. User asked to add phases and message bodies now, applying real backend/Android delivery later. No SDK, live account, credential, send, backend runtime or Android change is performed by this document. PRM11–PRM14 own future implementation.

Cost and architecture

Provider selected: OneSignal. Our existing backend hosts event eligibility, private inbox, templates, filters, quiet windows, quotas and durable jobs; OneSignal operates delivery. Official pricing checked 2026-10-13: Free mobile push currently applies to organizations with up to 1,000 monthly active users; verify counting/features before launch. No paid upgrade or paid-only targeting feature is authorized. Hosting a sender does not remove provider limits or our existing hosting costs. Official pricing.

Keep audience selection/advanced filters in our backend. Use the OneSignal Free API capabilities only, behind a provider port. Require explicit owner review if limits cease to fit; pause external sends and retain inbox/basic local alerts rather than incur unapproved charges.

Body templates proposed for pt-BR

Values below are placeholders, not actual station prices/promotions. Render exact Brazilian currency and product unit; include public source/time/conditions in the detail. Reject missing required placeholders rather than fabricate them.

  • new-price-v1 — Title: “Preço atualizado em {posto}”. Body: “{combustivel}: {preco_formatado}/{unidade}. Informado às {hora_local}.” Requires a current supported projection; a pending photo/submission alone cannot trigger this wording. Tap: public station/fuel detail with current source and time.
  • price-drop-v1 — Title: “Preço caiu em {posto}”. Body: “{combustivel} passou de {preco_anterior} para {preco_atual}/{unidade}. Confira a atualização.” Compare the same fuel/unit/condition and eligible source/time baseline. This does not paywall the existing local weekly drop alert.
  • promotion-v1 — Title: “Promoção informada em {posto}”. Body: “{beneficio_resumido}. {condicao_resumida}. Válida até {validade_local}. Confira as regras.” Source, actual terms, expiry and separate promotion consent are mandatory. Loyalty/app/payment restrictions stay explicit; promotional price never competes as an unconditional price.
  • premium-threshold-v1 — Title: “Seu alerta encontrou um preço”. Body: “{combustivel} a {preco_formatado}/{unidade} em {posto}, dentro do limite de {limite_formatado}/{unidade}.” Requires current verified Premium rule and supported fresh price; threshold filters do not buy ranking/trust.
  • premium-combined-v1 — Title: “Preço encontrado para seu filtro”. Body: “{posto}: {combustivel} a {preco_formatado}/{unidade}. {condicao_resumida}. Confira os detalhes.” All selected rule predicates must match; use truthful condition copy and selected city/station scope, no contributor GPS.
  • premium-digest-v1 — Title: “Resumo dos seus alertas”. Body: “{quantidade} opções atendem aos seus filtros em {cidade}. Atualizado às {hora_local}.” Count only still-valid candidates; no empty or invented count, best-price guarantee or implied complete city coverage.
  • private-generic-v1 — Title: “Atualização no abastevo”. Body: “Há uma atualização para você. Abra o app para conferir.” Optional lockscreen-safe fallback; opening still authenticates the current account before private data.

Proposed body envelope

Versioned internal fields: schema_version, event_id, event_type, template_id, locale, rendered title/body, created_at, expires_at, source reference/condition and an allowlisted typed navigation target. Recipient account/rule/device routing remains server-private and is translated to an opaque OneSignal alias/subscription set. Never send access/purchase tokens, email, precise GPS, receipt photos or financial records to the provider. No arbitrary web URL or HTML; unknown version/expired payload opens safe inbox recovery only.

OneSignal request fields are adapter-owned: configured app_id, target channel, localized headings/contents, minimal typed data, eligible opaque recipients, idempotency key and event-bounded TTL. Server App API key never enters the APK. Render content and target audience in our backend; no reliance on paid provider journeys/segmentation/timezone automation. Verify current API field support and Free availability in PRM11/12. Message API.

Require server-proven device/account binding and supported identity verification before private alias targeting; client login/external_id alone is not ownership. Logout/revoke/account switch must unlink old routing, and tap rechecks current ownership/expiry. Identity verification.

Experience and acceptance

New-price opt-in and promotional opt-in are distinct; marketing is not implied by free account registration. Premium enables new advanced filter combinations/windows, while existing free basic/follow alerts stay free. Keep category mute, quiet hours, cooldown, dedupe, TTL and best-effort windows; no notification flood or exact-time guarantee.

Provider acceptance, device receipt, OS display and user open are different states. Backend inbox remains authoritative under push loss/delay. No always-on tracking/advertising SDK configuration is authorized. Use existing Android components/notification channel conventions, Portuguese strings and accessibility. Real new-price/promotion publication rules and sender/SDK/privacy/cost/device tests must pass in their owning phases before any send.

This contract is independent of Google Play RTDN billing notifications. Current first-ten backend tasks continue unchanged; notifications implementation is future scope.

Fuel prices wiki

Source: AlexandreZanata/brazil-fuel-prices @ 08a54dc49c2e43a85aba56a7b56ae96d692cec61

Clone this wiki locally