This page describes the support and telemetry foundations that let a small DomiDo team operate the public Web/PWA open beta, learn from real users, and answer the core launch question: where did users drop, and why? DomiDo is built by Avvyland Limited (UK) and sells universal blocks and fasteners only; every construction shown on the platform is a user-generated design. A public beta cannot be run on abstract observability promises — it needs an implementable operating loop with six concrete parts: a single product-event pipeline that feeds analytics and the founder dashboard, a single founder dashboard for funnel, leads, jobs, failures, reservations, and pre-orders, a single support queue with a real reply path for users and admins, an error-and-log capture path with safe redaction, a small alert table with thresholds, owners, and runbook actions, and a beta-tester feedback loop that captures screen, severity, and release context. Without all six, the beta can technically launch but cannot be learned from or supported. The rest of this page describes those six surfaces and the data-class boundaries that keep them honest.
Phase A needs a small mandatory event set: not a business-intelligence warehouse, but the first learning loop. Each event has a required property shape that the backend serves through GET /api/config/product-events and that ingestion validates. Identity rules, consent rules, and source-attribution rules are owned by the backend and enforced on ingestion, and cookie-rejecting visitors still emit the essential operational events while optional analytics events drop. Failure to dispatch to the analytics provider keeps a local mirror for replay.
| Event | Required properties |
|---|---|
session_started |
Anonymous session id, user id if known, first-touch and last-touch source attribution, referrer, device class, consent state. |
signup_completed |
User id, authentication provider, source surface, source attribution. |
listing_viewed |
Listing id, designer id, source surface, source attribution, signed-in flag. |
listing_saved |
Listing id, user or session, source surface. |
create_started |
Mode, source surface, signed-in flag, source attribution. |
upload_validation_failed |
Draft id or session, format, size bucket, reason code. |
draft_saved |
Draft id, mode, stage, has-model flag, has-block-kit flag. |
generation_job_failed |
Job id, job type, stage, safe error code, retryable flag. |
listing_published |
Listing id, draft id, visibility, mode. |
checkout_started |
Checkout id, listing ids, expected total, source attribution. |
setup_intent_created |
Checkout id, pre-order id if known, Stripe mode, no-capture acknowledgement. |
setup_intent_succeeded |
Pre-order id, checkout id, expected total, card verification status. |
setup_intent_failed |
Checkout id, safe failure code, retryable flag. |
preorder_cancelled |
Pre-order id, reason category, days since created. |
support_conversation_created |
Support id, category, source surface, resource reference. |
support_conversation_replied |
Support id, responder role, response-time bucket. |
beta_feedback_submitted |
Beta-tester id or user id, flow, rating, reason category, free text stored as localised text. |
Support has to be minimal, but it has to be real. Users have to be able to contact support and report content, and the founder has to be able to triage, reply, and track first-response state. The user-facing surface is small: GET /support/conversations shows a user their tickets and status, GET /support/conversations/{conversationId} shows the thread, status, linked resource, and reply history, POST /support/conversations/{conversationId}/messages lets the user reply or add evidence, and PATCH /support/conversations/{conversationId} lets the user close or reopen where allowed. The admin surface mirrors that surface for staff: GET /admin/support/conversations shows the support queue with filters, priority, age, category, and the linked user or resource; GET /admin/support/conversations/{conversationId} opens one ticket with safe user and resource context; POST /admin/support/conversations/{conversationId}/messages lets the founder reply; and PATCH /admin/support/conversations/{conversationId} lets the founder assign, prioritise, change status or category, and link a bug, order, or pre-order. Every support conversation persists the conversation id, the requester user id or anonymous contact reference, the subject, category, priority, status, source surface, resource references, messages, attachments, assignee, last-customer-message timestamp, last-staff-response timestamp, first-response-due timestamp, response-time bucket, translation summary, and audit references.
Alerts are the minimum that wake the team. Each alert has a threshold, a named owner, and an expected runbook action. The principle is the same as the one stated on the Observability page: an alert wakes someone only if they are expected to act, and never wakes them for a problem that resolves itself in the next pull cycle.
| Alert | Severity | Threshold | Owner | Action |
|---|---|---|---|---|
| Production app unavailable | P0 | /readyz unavailable for two minutes or three consecutive checks. |
Founder / CTO | Roll back or disable the failing dependency. |
| Checkout blocked | P0 | Checkout confirmation failure rate above twenty percent over ten minutes or any accidental capture. | Founder / CTO | Stop launch traffic and inspect the Stripe and SetupIntent state. |
| Stripe webhook durable-store failure | P0 | Any valid webhook cannot be stored or enqueued. | Founder / CTO | Fix before accepting more pre-orders. |
| Audit fail-closed event | P0 | Any critical mutation blocked by audit persistence. | Founder / CTO | Restore audit persistence or disable the affected feature. |
| Job queue stuck | P1 | Ninety-fifth-percentile queue age above the configured limit or dead-letter count above threshold. | Pipeline owner | Drain, retry, or cut supported formats. |
| Upload validation spike | P1 | Invalid upload rate or parser failures above baseline. | Pipeline owner | Improve copy and narrow accepted formats. |
| Support backlog breach | P1 | The oldest open support ticket exceeds the same-business-day target. | Growth / Ops | Reply, update the FAQ or copy, and tag the recurring issue. |
| Analytics dispatch failure | P2 | Event dispatch failure above threshold for fifteen minutes. | Founder / CTO | Keep a local mirror and replay later. |
Beta testers are not normal customers yet. They need invites, cohorts, observed tasks, outcomes, issue links, consent, and interview notes. The platform tracks beta-tester records, invitations, beta feedback (rating, reason category, screen and context, release), and beta sessions where the founder watches a user complete a flow. The same data feeds the founder dashboard, so a recurring pattern in beta-tester feedback is visible alongside the funnel and the support themes rather than hidden in a separate tool.
Audit, structured logs, metrics, product analytics, support records, and reliability incidents are different things and they live in different stores. Mixing them creates privacy risk and useless dashboards, so the platform enforces strict class boundaries: the same fact never lives in multiple classes, and cookie-rejecting users still create audit, log, and reliability records while their optional product-analytics events drop.
| Class | Purpose | Examples | Retention rule |
|---|---|---|---|
| Audit | Tamper-evident record of security-relevant and consent-relevant actions. | Sign-in, role change, reservation create and cancel, publish, payment-state mutation. | Long retention with restricted access. |
| Structured log | Operational request, job, and provider correlation. | Request id, route, status, latency, safe error, provider call. | Short retention with redaction tests. |
| Metric | Time-series operational signal. | API latency, job queue depth, Stripe failure rate, search timeout rate. | Long retention as numeric aggregates. |
| Product analytics | Behavioural event for funnel and learning. | Listing view, create start, draft save, reservation create. | Pseudonymous, consent-gated, retention by policy. |
| Support record | Customer interaction history. | Conversation, messages, attachments, assignment. | Long retention with access control. |
| Reliability incident | Operational disruption record. | Incident severity, owner, runbook, correlation id. | Long retention as numeric and narrative record. |
Logs are structured, redacted, and correlated end to end. Each log line carries a request id or job id, a user or session reference when permitted, a route or worker name, a stage, a duration, a status, a safe error code, and provider-call references. Personally identifying details never appear in logs. Frontend crashes and session errors flow to the same error tracker as backend errors, so that a single correlation id can move from a client event to an API request to a job to a provider call to a user-visible state. The Phase A operational metrics that matter are API success rate and latency by route, job queue depth and lease, dead-letter rate, Stripe outcome rates, webhook duplicate handling, search timeout rate, and admin mutation throughput. The Phase A learning metrics that matter are activation rate, route-to-create conversion, create-stage drop-off, upload-failure reason distribution, draft-to-publish rate, listing-to-reservation rate, reservation cancellation rate, support-reason clusters, and cohort retention.
A developer can deploy the operations stack from the backend specification without guessing: the required environment values are the analytics write key, the log level, the error-tracker data source name, the alert webhook or email, the support inbox or provider, the analytics host or project, and the incident channel. The launch checklist passes only when end-to-end acceptance evidence exists for analytics ingestion, the founder dashboard, the support reply, an alert firing, log redaction, and beta-feedback capture, and the smoke-test script in the beta launch checklist covers each of these in turn.