Compare commits

...

32 Commits

Author SHA1 Message Date
The Dogfather e7032e46bf Merge pull request 'promote: dev → uat (GRO-1489 lint fixes)' (#433) from dev into uat
promote: dev → uat (GRO-1489 lint fixes) (#433)
2026-05-23 19:27:34 +00:00
The Dogfather fdd35a4cde Merge pull request 'fix(GRO-1489): resolve 7 lint errors blocking dev CI' (#429) from flea-flicker/gro-1489-lint-fixes into dev
CI / Lint & Typecheck (push) Successful in 21s
CI / Test (push) Successful in 24s
CI / Build (push) Successful in 22s
CI / Build & Push Docker Images (push) Failing after 42s
CI / Update Infra Image Tags (push) Has been skipped
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
fix(GRO-1489): resolve 7 lint errors blocking dev CI (#429)
2026-05-23 19:10:13 +00:00
Scrubs McBarkley 559274becd Merge pull request 'docs: add MCP-driven execution method to UAT playbook (GRO-1502)' (#432) from docs/GRO-1502-uat-mcp-migration into dev
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
CI / Lint & Typecheck (push) Successful in 22s
CI / Build (push) Successful in 21s
CI / Test (push) Successful in 24s
CI / Build & Push Docker Images (push) Successful in 33s
CI / Update Infra Image Tags (push) Failing after 1s
docs: add MCP-driven UAT execution method (GRO-1502)
2026-05-22 11:48:03 +00:00
Chris Farhood f3c56b43f0 docs: add Shedward Scissorhands UAT agent instructions (GRO-1502)
CI / Web E2E (Dev) (pull_request) Has been cancelled
CI / Deploy PR to groombook-dev (pull_request) Has been cancelled
CI / Lint & Typecheck (pull_request) Successful in 22s
CI / Test (pull_request) Successful in 27s
CI / Build (pull_request) Successful in 21s
CI / Build & Push Docker Images (pull_request) Successful in 57s
CI / Update Infra Image Tags (pull_request) Has been skipped
Mandates groombook-playwright MCP for all browser interaction during UAT.
Documents available MCP tools, execution workflow, and environment URLs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-22 11:40:35 +00:00
Chris Farhood 89b3d81a82 docs: add MCP-driven execution method to UAT playbook (GRO-1502)
UAT is now executed by Shedward Scissorhands via the groombook-playwright
MCP server. Legacy scripted Playwright suites remain for CI regression
only. Added Section 2 documenting the MCP tools, how test cases map to
MCP calls, and the role of legacy CI tests.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-22 11:39:56 +00:00
Flea Flicker 4a628ef3b7 fix(ci): remove CI-based E2E Tests job — use Playwright MCP instead
CI / Build (push) Successful in 21s
CI / Lint & Typecheck (push) Successful in 23s
CI / Test (push) Successful in 25s
CI / Build & Push Docker Images (push) Successful in 34s
CI / Update Infra Image Tags (push) Failing after 1s
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
E2E testing moved to Playwright MCP with Shedward Scissorhands in UAT
per GRO-904. The e2e job was blocking the docker job, which blocked the
entire release pipeline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 21:36:05 +00:00
Flea Flicker 15af4f0962 fix(ci): add 30s grace period after services report healthy
CI / Build (push) Successful in 24s
CI / Update Infra Image Tags (push) Has been skipped
CI / Lint & Typecheck (push) Successful in 23s
CI / E2E Tests (push) Failing after 45s
CI / Build & Push Docker Images (push) Has been skipped
CI / Test (push) Successful in 26s
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
Even after nginx is listening on port 80, there can be a brief window
where the first Playwright requests hit still-warming router logic or
upstream connection pool setup, causing inconsistent E2E failures.

Now the readiness step:
1. Polls until both http://localhost:8080 and http://localhost:3000/health
   return HTTP 200 (up to 60 attempts = 10 min max)
2. Once both are confirmed up, sleeps 30 additional seconds before
   proceeding to E2E tests — a settling period for nginx and the Node
   server to fully stabilize

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 21:19:22 +00:00
Flea Flicker 990bc4400c fix(ci): add explicit readiness wait for E2E services
CI / Lint & Typecheck (push) Successful in 25s
CI / Test (push) Successful in 27s
CI / Build (push) Successful in 24s
CI / E2E Tests (push) Failing after 46s
CI / Build & Push Docker Images (push) Has been skipped
CI / Update Infra Image Tags (push) Has been skipped
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
returns immediately after Docker reports
containers started, not after services inside those containers are actually
listening. This causes Playwright to hit nginx before it's ready.

Now:
- Start containers with  (no --wait)
- Poll http://localhost:8080 AND http://localhost:3000/health every 10s,
  up to 30 attempts (5 minutes total)
- Only proceed to E2E tests once both are reachable

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 21:13:20 +00:00
Flea Flicker c12935de9c fix(docker): add healthcheck + depends_on condition on web service
CI / Test (push) Successful in 28s
CI / Lint & Typecheck (push) Successful in 31s
CI / E2E Tests (push) Failing after 53s
CI / Build & Push Docker Images (push) Has been skipped
CI / Update Infra Image Tags (push) Has been skipped
CI / Build (push) Successful in 31s
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
Previously web started immediately after the api container launched, not
after it was ready. Playwright tests then hit the web server before the
nginx process had fully started, causing connection refused errors.

Now:
- api has a 30s startup grace via start_period and 20 retries
- web waits for api to be healthy (not just started)
- both services verify readiness before dependent steps proceed

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 21:09:44 +00:00
The Dogfather 09edd1b8ec Merge pull request 'Promote dev → uat: fix(e2e) PLAYWRIGHT_BASE_URL + host.docker.internal (GRO-1496)' (#431) from dev into uat
Promote dev → uat: fix(e2e) PLAYWRIGHT_BASE_URL + host.docker.internal (GRO-1496) (#431)
2026-05-21 21:04:20 +00:00
The Dogfather 9b49b6388d Merge pull request 'fix(e2e): respect PLAYWRIGHT_BASE_URL env var and add host.docker.internal resolution' (#430) from flea/gro-1496-e2e-err-connection-refused into dev
CI / Test (push) Successful in 22s
CI / Lint & Typecheck (push) Successful in 23s
CI / Build (push) Successful in 24s
CI / E2E Tests (push) Failing after 3m45s
CI / Build & Push Docker Images (push) Has been skipped
CI / Update Infra Image Tags (push) Has been skipped
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
fix(e2e): respect PLAYWRIGHT_BASE_URL env var and add host.docker.internal resolution (#430)
2026-05-21 21:04:04 +00:00
Flea Flicker fe5de5fec8 fix(ci): use localhost instead of host.docker.internal for Playwright
CI / Test (push) Successful in 25s
CI / Lint & Typecheck (push) Successful in 23s
CI / Build (push) Successful in 23s
CI / E2E Tests (push) Failing after 5m31s
CI / Build & Push Docker Images (push) Has been skipped
CI / Update Infra Image Tags (push) Has been skipped
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
host.docker.internal is a Docker Desktop feature unavailable on Gitea Actions
ubuntu-latest runners. Linux runners can reach the Docker Compose service
via localhost when using docker compose expose/published ports.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 20:58:02 +00:00
Flea Flicker 82f1e3856f fix(e2e): respect PLAYWRIGHT_BASE_URL env var and add host.docker.internal resolution
CI / Test (pull_request) Successful in 28s
CI / Lint & Typecheck (pull_request) Successful in 31s
CI / E2E Tests (pull_request) Successful in 1m32s
CI / Build (pull_request) Successful in 2m32s
CI / Build & Push Docker Images (pull_request) Successful in 35s
CI / Update Infra Image Tags (pull_request) Has been skipped
CI / Web E2E (Dev) (pull_request) Has been cancelled
CI / Deploy PR to groombook-dev (pull_request) Has been cancelled
The Playwright config hardcoded localhost:8080 as baseURL, ignoring
the PLAYWRIGHT_BASE_URL env var set in CI. Docker Compose was also
missing extra_hosts to resolve host.docker.internal on Gitea Actions
runners (which use DIND).

Fixes GRO-1496.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 20:53:30 +00:00
The Dogfather 7bb7d8c32b Merge pull request 'promote: dev → uat (GRO-1369 types sync)' (#428) from dev into uat
Merge dev → uat: GRO-1369 types sync, cascade logic, SMS consent
2026-05-21 20:53:19 +00:00
Flea Flicker 526251b63a fix: resolve lint errors and xlarge mismatch for dev→uat promotion
CI / Test (push) Successful in 26s
CI / Lint & Typecheck (push) Successful in 27s
CI / E2E Tests (push) Failing after 3m27s
CI / Update Infra Image Tags (push) Has been skipped
CI / Build (push) Successful in 24s
CI / Build & Push Docker Images (push) Has been skipped
CI / Web E2E (Dev) (push) Has been cancelled
CI / Deploy PR to groombook-dev (push) Has been cancelled
- Remove unused gte/lt/ne imports from cascade.ts
- Prefix unused params originalEndTime, originalStartTime, newStartTime
  with underscore in cascade.ts and appointments.ts callers
- Remove unused petCoatType query param from book.ts availability route
- Align xlarge value: Book.tsx now uses "xlarge" (no hyphen) everywhere
  to match the Zod booking schema

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-21 20:28:43 +00:00
The Dogfather 6f160dde51 Merge pull request 'promote: dev → uat (GRO-1248 path prefix fix)' (#425) from dev into uat
promote: dev → uat (GRO-1248 path prefix fix) (#425)
2026-05-20 13:01:26 +00:00
the-dogfather-cto[bot] 733af4f5f2 Merge pull request #420 from groombook/dev
chore: promote dev → uat (GRO-1289 CI path fix)
2026-05-14 21:03:16 +00:00
the-dogfather-cto[bot] 13abbdcec8 chore: promote dev to uat — GRO-1287 ci.yml path fix (#419)
chore: promote dev to uat (GRO-1287 ci.yml path fix)
2026-05-14 20:49:13 +00:00
the-dogfather-cto[bot] e4e783dec6 chore: promote dev to uat — VITE_API_URL fix (GRO-1280, GRO-1206)
chore: promote dev to uat — VITE_API_URL fix (GRO-1280)
2026-05-14 20:32:09 +00:00
the-dogfather-cto[bot] 1a88528eae promote: dev → uat (GRO-1236 OAuth callback fix)
promote: dev → uat (GRO-1236 OAuth callback fix)
2026-05-14 19:36:13 +00:00
Chris Farhood 0f6a5ebe35 Promote dev→uat: OAuth callback session fix (GRO-1236) 2026-05-14 19:25:42 +00:00
the-dogfather-cto[bot] 121735edca promote: dev → uat (GRO-1207 portal Communication tab real backend)
promote: dev → uat (GRO-1207 portal Communication tab real backend)
2026-05-14 16:59:09 +00:00
the-dogfather-cto[bot] 5b2f45e5f3 chore: promote dev → uat (GRO-1212 portal test mock fix)
chore: promote dev → uat (GRO-1212 portal test mock fix)
2026-05-14 12:08:38 +00:00
the-dogfather-cto[bot] ff0bd2903e promote: dev → uat (GRO-1208 conversations API + GRO-1211 telnyx webhook fix)
promote: dev → uat (GRO-1208 conversations API + GRO-1211 telnyx webhook fix)
2026-05-14 08:45:38 +00:00
the-dogfather-cto[bot] 831b90dbe2 Merge dev→uat: auth rate limiting (GRO-1024)
chore: promote dev → uat (fix auth rate limits)
2026-05-11 03:40:46 +00:00
the-dogfather-cto[bot] 4b4ffa0ca4 Promote dev → uat: TELNYX_WEBHOOK_SECRET .env.example
Promote dev → uat: TELNYX_WEBHOOK_SECRET .env.example
2026-05-11 02:27:54 +00:00
the-dogfather-cto[bot] f0f271e046 feat(GRO-106): inbound Telnyx webhook + persistence (#378) (#388)
* feat(GRO-106): messaging schema + migrations

- Add conversations, messages, message_attachments, message_consent_events tables
- Add messagingChannelEnum, messageDirectionEnum, messageStatusEnum, messageConsentKindEnum
- Extend business_settings with messagingPhoneNumber and telnyxMessagingProfileId columns
- Add required indexes and unique constraints with cascade-on-delete FKs
- Add migration 0030_messaging.sql



* fix(GRO-981): restore journal entries and add DESC to indexes

- _journal.json: restore idx 28 (0028_sms_reminders), add idx 29
  (0029_db_indexes_constraints), renumber 0030_messaging to idx 30
  (was missing 0028 and 0029 entries — they were silently skipped)
- schema.ts: add .desc() to conversations.lastMessageAt and
  messages.createdAt indexes per spec
- 0030_messaging.sql: add DESC to both generated index statements



* feat(GRO-106): inbound Telnyx webhook + persistence

- Add POST /api/webhooks/telnyx/messaging route with HMAC signature verification
- Add services/messaging/inbound.ts: findOrCreateConversation, upsertMessage (idempotent on providerMessageId), delivery receipt handling
- Register telnyxWebhooksRouter in index.ts (before auth middleware)
- Add unit tests for signature validation, find-or-create, idempotent insert, delivery receipt



* fix(GRO-982): address all QA blocking failures

- #7: Extract validateTelnyxSignature in sms.ts as standalone exported fn,
  reuse in TelnyxProvider.validateWebhookSignature and telnyx.ts route
- #1: Replace uuid v4 import with crypto.randomUUID() (built-in, no dep)
- #2: Remove updatedAt from messages update in handleMessageFinalized
  (no such column exists)
- #3: Fix test import path ../../ → ../../../ for telnyx route import
- #4: validateTelnyxSignature accepts string | undefined | null to match
  Hono c.req.header() return type
- #5&6: Add null guards for .returning() results in findOrCreateConversation
  and upsertMessage
- #8: Remove dead buildFindOrCreateConversationParams function
- #9: Remove unused imports (messageDirectionEnum, messageStatusEnum,
  resolveBusinessIdByMessagingNumber in test)
- #10: Wrap upsertMessage insert in try/catch; unique violation returns
  {isNew: false} instead of crashing
- #11: Add EOF newlines to all modified files



* chore: add uuid dependency for messaging services

* fix(GRO-982): address 5 test failures in inbound webhook

- Fix signature route tests: use /messaging not full mount path
- Fix handleMessageReceived mock order: business lookup first
- Fix stale mock state: add full mockReset in handleMessageFinalized beforeEach
- Fix delivery logic: set delivered for all message.finalized events
- Deduplicate test that was accidentally added twice



* fix(GRO-982): look up or create client by phone before inserting conversation

Fixes FK constraint violation where clientId was set to businessSettings.id
or a random UUID. Now looks up clients.phone = clientPhone first; if no match,
creates a placeholder client with phone as name and a placeholder email.

* fix(GRO-982): address QA round 4 blocking failures

- Fix URL in signature tests: use /messaging not full path
- Reorder mocks: businessSettings first, then conversations, clients, messages
- Add mockDb.mockReset in handleMessageFinalized beforeEach
- Remove direction guard: set delivered for any message.finalized

* fix(GRO-982): add missing message insert mock in handleMessageReceived test

* fix(GRO-982): simplify test mocks to match actual code flow

---------

Co-authored-by: groombook-engineer[bot] <269742240+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Chris Farhood <chris@farhood.org>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-11 00:51:17 +00:00
the-dogfather-cto[bot] 673b85b64b Merge pull request #386 from groombook/dev
chore: promote dev → uat (GRO-1036 security fixes)
2026-05-04 22:53:58 +00:00
the-dogfather-cto[bot] a368d567d8 promote dev → uat: portal mobile overflow fix (GRO-730) (#384)
promote dev → uat: portal mobile overflow fix (GRO-730)
2026-05-04 21:25:36 +00:00
the-dogfather-cto[bot] 5332147ac1 Merge dev → uat: 10DLC pilot registration runbook (GRO-106)
promote dev → uat: 10DLC pilot registration runbook (GRO-106)
2026-05-04 20:55:50 +00:00
the-dogfather-cto[bot] b38de28d2e Merge pull request #380 from groombook/dev
promote: dev → uat (GRO-693 E2E mock fixes)
2026-05-04 15:16:52 +00:00
the-dogfather-cto[bot] 66a80cf9e7 Merge pull request #376 from groombook/dev
promote: GRO-106 messaging schema → UAT
2026-05-04 02:25:31 +00:00
4 changed files with 115 additions and 43 deletions
+1 -36
View File
@@ -53,41 +53,6 @@ jobs:
- name: Run tests
run: pnpm test
e2e:
name: E2E Tests
runs-on: ubuntu-latest
needs: [lint-typecheck, test]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: '9.15.4'
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Playwright browsers
run: pnpm --filter @groombook/e2e exec playwright install --with-deps chromium
- name: Start Docker Compose stack
run: docker compose up -d --wait
timeout-minutes: 5
- name: Run E2E tests
run: pnpm --filter @groombook/e2e test
env:
PLAYWRIGHT_BASE_URL: http://host.docker.internal:8080
- name: Stop Docker Compose stack
if: always()
run: docker compose down
build:
name: Build
runs-on: ubuntu-latest
@@ -115,7 +80,7 @@ jobs:
docker:
name: Build & Push Docker Images
runs-on: ubuntu-latest
needs: [build, e2e]
needs: [build]
outputs:
tag: ${{ steps.version.outputs.tag }}
steps:
+50
View File
@@ -0,0 +1,50 @@
# Shedward Scissorhands — UAT Agent Instructions
You are the GroomBook User Acceptance Tester. Your sole job is to execute UAT playbooks against deployed environments and report results.
## Mandatory Tooling
You MUST use the **groombook-playwright MCP server** (`mcp__playwright-groombook__*` tools) for ALL browser interaction. Do not:
- Run scripted Playwright suites (`npx playwright test`, `pnpm test:e2e`, etc.)
- Use manual browser commands or shell-based browser automation
- Open browsers outside the MCP server
Every page navigation, click, form fill, and verification MUST go through MCP tools.
## Available MCP Tools
| Tool | When to use |
|------|-------------|
| `browser_navigate` | Open a URL |
| `browser_snapshot` | Read page state (preferred over screenshot for assertions) |
| `browser_take_screenshot` | Capture visual evidence |
| `browser_click` | Click an element (use ref from snapshot) |
| `browser_fill_form` | Fill form fields |
| `browser_type` | Type text into focused element |
| `browser_press_key` | Press keyboard keys |
| `browser_select_option` | Select dropdown options |
| `browser_hover` | Hover over elements |
| `browser_wait_for` | Wait for elements or navigation |
| `browser_console_messages` | Check for JS errors |
| `browser_network_requests` | Inspect API calls |
| `browser_evaluate` | Run JS in page context |
| `browser_resize` | Test responsive layouts |
| `browser_close` | Close browser session |
## Execution Workflow
1. Read the `UAT_PLAYBOOK.md` in the repo being tested.
2. For each test case, translate the human-readable steps into MCP tool calls.
3. Capture evidence: use `browser_snapshot` for assertions, `browser_take_screenshot` for visual proof.
4. Report pass/fail per test case with evidence.
5. If a test fails, document: severity, steps to reproduce, actual vs expected, and attach screenshots.
## Environments
| Environment | URL | Auth |
|-------------|-----|------|
| Dev | `https://dev.groombook.dev` | Dev login selector (no OIDC) |
| UAT | `https://uat.groombook.dev` | Authentik OIDC at `https://auth.farh.net` |
| Production | `https://demo.groombook.dev` | Authentik OIDC |
| Site | `https://groombook.farh.net` | No auth required |
+48 -6
View File
@@ -4,7 +4,49 @@
GroomBook is an open-source, self-hostable pet grooming business management & CRM platform. The monorepo contains the Hono API (`apps/api`), React PWA web app (`apps/web`), E2E tests (`apps/e2e`), and shared packages (`packages/db`, `packages/types`). Tech stack: Hono + React 19 + Vite + PostgreSQL + Drizzle ORM + Authentik OIDC.
## 2. Environments
## 2. Execution Method
All UAT is executed by **Shedward Scissorhands** via the **groombook-playwright MCP server**. No manual browser checks or scripted Playwright suites are used for UAT.
### MCP Tools
Shedward uses the `mcp__playwright-groombook__*` tool family:
| Tool | Purpose |
|------|---------|
| `browser_navigate` | Navigate to a URL |
| `browser_snapshot` | Capture accessibility snapshot (preferred over screenshot) |
| `browser_take_screenshot` | Capture visual screenshot when needed |
| `browser_click` | Click an element by ref or selector |
| `browser_fill_form` | Fill form fields |
| `browser_type` | Type text into focused element |
| `browser_press_key` | Press keyboard keys (Enter, Tab, etc.) |
| `browser_select_option` | Select dropdown options |
| `browser_hover` | Hover over elements |
| `browser_wait_for` | Wait for elements or conditions |
| `browser_console_messages` | Check console for errors |
| `browser_network_requests` | Inspect network traffic |
| `browser_evaluate` | Run JavaScript in page context |
| `browser_tabs` | Manage browser tabs |
| `browser_close` | Close browser |
### How Test Cases Map to MCP Calls
Each test case in Section 4 describes steps like "Navigate to X" or "Click Y". Shedward translates these to MCP tool calls:
- **"Navigate to [URL]"** → `browser_navigate` with the environment URL
- **"Click [element]"** → `browser_snapshot` to find the element ref, then `browser_click`
- **"Fill in [field]"** → `browser_fill_form` or `browser_click` + `browser_type`
- **"Verify [state]"** → `browser_snapshot` and inspect the accessibility tree
- **"Check for errors"** → `browser_console_messages` + `browser_snapshot`
Shedward reads this playbook, executes each test case via MCP tools, captures evidence (snapshots/screenshots), and reports pass/fail per test case.
### Legacy CI Tests
The scripted Playwright suites in `apps/e2e/` and `apps/web/e2e/` are retained for CI regression testing only. They are **not** the primary UAT mechanism. UAT is exclusively MCP-driven by Shedward.
## 3. Environments
| Environment | URL | Notes |
|-------------|-----|-------|
@@ -14,7 +56,7 @@ GroomBook is an open-source, self-hostable pet grooming business management & CR
**Local Development:** Run `docker compose up --build` at repository root. Web app available at `localhost:8080`, API at `localhost:3000`.
## 3. Pre-conditions
## 4. Pre-conditions
- UAT environment is accessible at `https://uat.groombook.dev`
- Test accounts are seeded with the following personas:
@@ -29,7 +71,7 @@ GroomBook is an open-source, self-hostable pet grooming business management & CR
- Stripe test keys are configured for payment flow testing
- Email/SMS providers (Telnyx, etc.) are configured for notification testing
## 4. Test Cases
## 5. Test Cases
### 4.1 Authentication
@@ -252,7 +294,7 @@ GroomBook is an open-source, self-hostable pet grooming business management & CR
| TC-APP-4.21.10 | Whitespace trimming | 1. Send ` START ` or `\tSTOP\n` | Keywords are trimmed before matching |
| TC-APP-4.21.11 | Non-keyword messages ignored | 1. Send `STOP IT`, `help me`, `hello` | Returns null from `detectKeyword`, no consent event inserted, no reply sent |
| TC-APP-4.21.12 | Consent event audit log | 1. After any keyword, query `messageConsentEvents` table | Record exists with correct `clientId`, `businessId`, `kind`, and `source: "sms_keyword"` |
## 5. Pass/Fail Criteria
## 6. Pass/Fail Criteria
**Pass:** All test cases execute without errors. Expected results match actual results. No regressions are observed. All functionality works as documented.
@@ -265,7 +307,7 @@ GroomBook is an open-source, self-hostable pet grooming business management & CR
**Regressions:** If a previously working feature fails during this UAT run, it is considered a regression and must be addressed before the release can proceed.
## 6. Update Policy
## 7. Update Policy
**Any PR that changes user-facing behaviour MUST update this file.**
@@ -275,4 +317,4 @@ When modifying features that affect:
- Configuration (settings, integrations)
- Data visibility (reports, search, filtering)
The corresponding test case(s) in Section 4 must be updated to reflect the new behaviour. The PR description must reference which playbook section was updated (e.g., "Updated UAT_PLAYBOOK.md §4.5 — new appointment group scheduling feature").
The corresponding test case(s) in Section 5 must be updated to reflect the new behaviour. The PR description must reference which playbook section was updated (e.g., "Updated UAT_PLAYBOOK.md §4.5 — new appointment group scheduling feature").
+16 -1
View File
@@ -43,6 +43,12 @@ services:
condition: service_healthy
migrate:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
interval: 5s
timeout: 5s
retries: 20
start_period: 10s
web:
build:
@@ -50,8 +56,17 @@ services:
dockerfile: apps/web/Dockerfile
ports:
- "8080:80"
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- api
api:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"]
interval: 5s
timeout: 5s
retries: 20
start_period: 10s
volumes:
postgres_data: