Skip to content

Design: In-App Feedback & ADO Integration ​

AB#: 4424–4427
ADR: ADR-0041
Status: Active


Overview ​

A multi-step feedback form on the About page lets authenticated members submit bug reports, feature requests, and general feedback. Each submission creates an ADO work item under Epic AB#4424 using the existing AZURE_DEVOPS_EXT_PAT.


API ​

POST /api/v1/feedback ​

Auth: requireAuth (any role)
Rate limit: inherits global 100 req/15 min; additionally enforced at 5/hr per userId in the handler

Request body:

json
{
  "type": "bug | feature | feedback | praise",
  "area": "auth | profile | members | family | admin | minister | media | calendar | groups | messages | marketplace | homeschool | other",
  "title": "string (3–200 chars)",
  "body": "string (10–5000 chars)",
  "steps": "string? (bug only, up to 2000 chars)",
  "expectedBehavior": "string? (bug only)",
  "deviceInfo": "string? (bug only, auto-collected)",
  "usageFrequency": "low | sometimes | often | daily (feature only)"
}

Response 201:

json
{ "data": { "workItemId": 4500, "url": "https://dev.azure.com/..." } }

Response 429: rate limit exceeded
Response 422: validation error

ADO call: HTTP POST to https://dev.azure.com/hybridcloudsolutions/Heritage Community Hub/_apis/wit/workItems/$Bug (or $User Story) with AZURE_DEVOPS_EXT_PAT Bearer token.


Web form ​

Location: apps/web/src/pages/AboutPage.tsx — new FeedbackForm section below existing contact info.

Flow:

Step 1 ─ Type selector
  [Bug Report]  [Feature Request]  [Feedback]  [Praise]

Step 2 ─ Feature area dropdown
  Select the area of the app this relates to
  [Sign In / Account ▾]  ...  [Other]

Step 3 ─ Type-specific fields + instructions
  (fields change based on type selected in Step 1)

Step 4 ─ Submit → confirmation card with ADO item ID

Instructions copy (shown on Step 3):

Bug reports: The more detail you give, the faster we can fix it. Describe exactly what happened, what you expected to see, and the steps that led to the issue. Screenshots can be added after we respond.

Feature requests: Help us understand the problem you're trying to solve, not just the solution. The best features come from real needs, and we want to hear yours.

General feedback: Any thought — big or small — is welcome. If something made your experience better or worse, we want to know.


Field validation (Zod schema) ​

typescript
const FeedbackBodySchema = z.object({
  type: z.enum(['bug', 'feature', 'feedback', 'praise']),
  area: z.enum([
    'auth', 'profile', 'members', 'family', 'admin', 'minister',
    'media', 'calendar', 'groups', 'messages', 'marketplace', 'homeschool', 'other',
  ]),
  title: z.string().min(3).max(200),
  body: z.string().min(10).max(5000),
  steps: z.string().max(2000).optional(),
  expectedBehavior: z.string().max(1000).optional(),
  deviceInfo: z.string().max(500).optional(),
  usageFrequency: z.enum(['low', 'sometimes', 'often', 'daily']).optional(),
})

ADO work item construction ​

Work item type:  Bug → type=bug; User Story → everything else
Title:           "[Feedback] <type> — <area>: <title>"
Tags:            "member-feedback; feedback:<area>"
Priority:        bug=1, feature=2, feedback=3, praise=3
Parent:          AB#4424 (via relation)
Description:     Markdown body built from all submitted fields + submitter email

Files to create / modify &ZeroWidthSpace;

FileAction
apps/api/src/features/feedback/feedback.schema.tsNew — Zod schema
apps/api/src/features/feedback/feedback.service.tsNew — ADO REST call logic
apps/api/src/features/feedback/feedback.controller.tsNew — handler
apps/api/src/features/feedback/feedback.router.tsNew — route registration
apps/api/src/app.tsRegister feedback router
apps/web/src/pages/AboutPage.tsxAdd FeedbackForm component

Security checklist &ZeroWidthSpace;

  • [x] Auth required — no anonymous submissions
  • [x] Zod validation before any ADO call
  • [x] Rate limiting (5/hr per user)
  • [x] No secrets in response body (ADO PAT never returned)
  • [x] User email appended to description, not stored separately
  • [x] Title/body sanitized (Zod string constraints prevent oversized input)

Heritage Community Hub — Internal. Access restricted via Cloudflare Access + Entra ID.