Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
373 commits
Select commit Hold shift + click to select a range
f459d04
Merge remote-tracking branch 'origin/support-platform' into agent1/st…
Andreas-Froyland Aug 18, 2026
c23a8a5
merge: ratify Stage 04 parallel-agents split (agent1/stage-04 docs)
Andreas-Froyland Aug 18, 2026
7740503
feat(support): extend the email layer and give ChannelDriver an outbo…
Andreas-Froyland Aug 18, 2026
ded1976
docs(support): correct the pinned attachment type and record SUP-04-1…
Andreas-Froyland Aug 18, 2026
0e8ba96
feat(support): add lib/support-email.ts composition helpers (SUP-04-2)
Andreas-Froyland Aug 18, 2026
bbf250d
merge: sync origin/support-platform (SUP-04-2 landed)
Andreas-Froyland Aug 22, 2026
e62d887
merge: integrate agent1/stage-04 (SUP-04-1 corrected) into support-pl…
Andreas-Froyland Aug 22, 2026
db896c5
chore(todo): check off SUP-04-1, SUP-04-2 -- integrated into support-…
Andreas-Froyland Aug 22, 2026
ebe8d1d
feat(support): per-inbox From/Reply-To/signature + sending authorizat…
Andreas-Froyland Aug 22, 2026
c165315
chore(todo): check off SUP-04-6
Andreas-Froyland Aug 22, 2026
cc8c476
docs(support): record SUP-04-6 landing for Agent 1's SUP-04-4
Andreas-Froyland Aug 22, 2026
e7fddc1
feat(support): add supportOutboundDelivery outbox + claim/retry worke…
Andreas-Froyland Aug 22, 2026
7edf2c8
merge: sync origin/support-platform (SUP-04-6 landed)
Andreas-Froyland Aug 22, 2026
a8cae92
feat(support): add resetOutboundDeliveryForRetry for SUP-04-10's retr…
Andreas-Froyland Aug 22, 2026
dd16d28
docs(support): record SUP-04-3 landing for Agent 1's SUP-04-4 and Age…
Andreas-Froyland Aug 22, 2026
8d94454
merge: integrate agent1/stage-04 (SUP-04-3) into support-platform
Andreas-Froyland Aug 22, 2026
0bbafcb
chore(todo): check off SUP-04-3 -- integrated into support-platform
Andreas-Froyland Aug 22, 2026
504ee57
feat(support): agent attachment upload via presign, size cap + type a…
Andreas-Froyland Aug 22, 2026
2258133
chore(todo): check off SUP-04-7
Andreas-Froyland Aug 22, 2026
c588879
wip(support): SUP-04-4 outgoing-reply wiring, before reconciling SUP-…
Andreas-Froyland Aug 23, 2026
9ea4615
merge: sync origin/support-platform (SUP-04-7 landed)
Andreas-Froyland Aug 23, 2026
d4c0f91
fix(support): align SUP-04-4's attachment handling with SUP-04-7's re…
Andreas-Froyland Aug 23, 2026
233ada8
docs(support): record SUP-04-4/04-5 landing for Agent 2's SUP-04-10/0…
Andreas-Froyland Aug 23, 2026
b16ddff
feat(support): add auto-reply with all four guards (SUP-04-8)
Andreas-Froyland Aug 23, 2026
e3caac7
docs(support): record SUP-04-8 landing and two Stage 06 judgment calls
Andreas-Froyland Aug 23, 2026
14dc2e6
merge: integrate agent1/stage-04 (SUP-04-4, 04-5, 04-8) into support-…
Andreas-Froyland Aug 23, 2026
c9c21f0
chore(todo): check off SUP-04-4, SUP-04-5, SUP-04-8 -- integrated int…
Andreas-Froyland Aug 23, 2026
d57b595
feat(support): delivery status in the thread UI + retry action (SUP-0…
Andreas-Froyland Aug 23, 2026
4e6022b
chore(todo): check off SUP-04-10
Andreas-Froyland Aug 23, 2026
68d104b
test(support): E2E for the outbound round trip -- inbound -> agent re…
Andreas-Froyland Aug 23, 2026
d0a9b15
chore(todo): check off SUP-04-11
Andreas-Froyland Aug 23, 2026
2f0503c
feat(support): delivery/bounce webhook, keyed on supportDeliveryEvent…
Andreas-Froyland Aug 23, 2026
fd01de5
docs(support): record SUP-04-9 landing -- Stage 04's biggest open risk
Andreas-Froyland Aug 23, 2026
61ba2b4
fix(test): clean up leftover pending outbox rows in integration tests
Andreas-Froyland Aug 23, 2026
5231919
merge: integrate agent1/stage-04 (SUP-04-9) into support-platform
Andreas-Froyland Aug 23, 2026
3f8058c
chore(todo): check off SUP-04-9 -- Stage 04 complete, 11/11
Andreas-Froyland Aug 23, 2026
83603d2
fix(support): recover outbound deliveries after restart
Andreas-Froyland Aug 24, 2026
dbfe74e
docs(support): define stage 1-4 hardening
Andreas-Froyland Aug 25, 2026
f72ecf3
fix(support): harden stage 1-4 review findings
Andreas-Froyland Aug 25, 2026
0ae4d13
docs(support): plan stage 1-4 hardening implementation
Andreas-Froyland Aug 25, 2026
5abb5f6
feat(support): add hardening data contracts
Andreas-Froyland Aug 25, 2026
6bff25e
fix(support): defer unsafe index cutovers
Andreas-Froyland Aug 25, 2026
d6a2096
feat(support): rank inbox access
Andreas-Froyland Aug 25, 2026
df7cbdd
fix(support): harden ranked inbox access
Andreas-Froyland Aug 25, 2026
ceb6820
feat(support): enforce inbox roles
Andreas-Froyland Aug 25, 2026
7d8bb8f
test(support): execute route authorization inventory
Andreas-Froyland Aug 25, 2026
c1c18e6
test(support): make route inventory assertions exact
Andreas-Froyland Aug 25, 2026
5e071f8
fix(support): preserve joined inbox access
Andreas-Froyland Aug 25, 2026
025d205
feat(support): reflect inbox permissions in the UI
Andreas-Froyland Aug 25, 2026
7402bb9
fix(support): harden permission recovery and fixtures
Andreas-Froyland Aug 25, 2026
2e74a5b
fix(support): close stale context recovery races
Andreas-Froyland Aug 25, 2026
8fa5d7c
fix(support): guard final stale recovery writes
Andreas-Froyland Aug 25, 2026
2db2d33
fix(support): close remaining recovery races
Andreas-Froyland Aug 25, 2026
af8d1a2
test(support): stabilize team-switch recovery proof
Andreas-Froyland Aug 25, 2026
f4d3f47
test(support): prove stale contact recovery isolation
Andreas-Froyland Aug 25, 2026
4a97882
feat(support): auto-link authenticated feedback
Andreas-Froyland Aug 25, 2026
4ac6380
fix(support): close auto-link race windows
Andreas-Froyland Aug 25, 2026
e8973e3
docs(support): finalize auto-link verification report
Andreas-Froyland Aug 25, 2026
43939e4
test(support): keep auto-link fixture lint-clean
Andreas-Froyland Aug 25, 2026
20bff19
docs(support): record final auto-link lint count
Andreas-Froyland Aug 25, 2026
a899276
fix(support): serialize contact identity lifecycle
Andreas-Froyland Aug 26, 2026
afbe6f7
fix(support): serialize contact unlinking
Andreas-Froyland Aug 26, 2026
a20950d
test(support): prove cross-team lock independence
Andreas-Froyland Aug 26, 2026
82cd6f5
feat(support): bound contact timelines
Andreas-Froyland Aug 26, 2026
36aa8f3
fix(support): harden timeline pagination races
Andreas-Froyland Aug 26, 2026
c20ea61
feat(support): own attachment upload sessions
Andreas-Froyland Aug 27, 2026
a0145b4
feat(support): finalize attachment messages
Andreas-Froyland Aug 27, 2026
035e237
feat(support): clean attachment upload sessions
Andreas-Froyland Aug 27, 2026
c3c19b1
docs(support): re-cut Stage 05 for a 1-3 agent MVP
Andreas-Froyland Aug 30, 2026
5b82348
docs(support): link Stage 05 backlog to issues #37-#46
Andreas-Froyland Aug 30, 2026
fc20edf
chore(support): checkpoint stage 1-4 review
Andreas-Froyland Aug 30, 2026
f19de54
docs(support): preserve task 5 review history
Andreas-Froyland Aug 30, 2026
6863374
docs(support): finalize migration handoff
Andreas-Froyland Aug 30, 2026
9212e5a
fix(support): keep attachment upload phases reactive
Andreas-Froyland Sep 1, 2026
8ac2051
docs(support): hand off completed attachment review
Andreas-Froyland Sep 1, 2026
610b578
fix(support): scope email threading to inboxes
Andreas-Froyland Sep 1, 2026
6049e9c
docs(support): hand off completed threading review
Andreas-Froyland Sep 1, 2026
47ae7f4
fix(support): correlate delivery events through outbox
Andreas-Froyland Sep 1, 2026
1780caf
docs(support): hand off completed delivery audit
Andreas-Froyland Sep 1, 2026
3ced66d
fix(support): schedule bounded outbound retries
Andreas-Froyland Sep 1, 2026
1fcece2
docs(support): hand off completed retry audit
Andreas-Froyland Sep 1, 2026
f75cc74
chore(build): make database operations explicit
Andreas-Froyland Sep 1, 2026
86a4cb9
docs(support): hand off completed build audit
Andreas-Froyland Sep 1, 2026
ac95c41
test(support): prove multi-instance realtime
Andreas-Froyland Sep 3, 2026
ec8937f
fix(auth): pin secure-cookie selection
Andreas-Froyland Sep 3, 2026
0ac0472
chore(dev): make Vite dev allowed hosts env-driven
Andreas-Froyland Sep 3, 2026
e0ea08f
docs(support): record task 15 and its production defect
Andreas-Froyland Sep 3, 2026
6a89fe2
chore(support): record hardening observability
Andreas-Froyland Sep 4, 2026
1069580
fix(test): make the worktree E2E path run against its own server
Andreas-Froyland Sep 4, 2026
41cecd5
docs(support): close out the stage 01-04 hardening tasks
Andreas-Froyland Sep 4, 2026
ddb1716
fix(support): close the review gate's important findings
Andreas-Froyland Sep 6, 2026
ab572af
docs(support): record the final review gate outcome
Andreas-Froyland Sep 6, 2026
3375287
fix(support): resolve the review gate's minor findings
Andreas-Froyland Sep 6, 2026
393ad47
docs(support): record the minor findings as resolved
Andreas-Froyland Sep 6, 2026
ec9f8df
chore: stop tracking generated SDD review packages
Andreas-Froyland Sep 6, 2026
4a19726
merge: integrate stage 01-04 hardening review
Andreas-Froyland Sep 6, 2026
e92c638
docs(support): mark the stage 01-04 hardening integrated
Andreas-Froyland Sep 7, 2026
56484fe
chore(support): queue stage 05a work
Andreas-Froyland Sep 7, 2026
f005c24
docs(support): record stage 05a execution ledger
Andreas-Froyland Sep 7, 2026
20df161
feat(support): add conversation claim assignment
Andreas-Froyland Sep 7, 2026
b94c2e7
fix(support): make explicit claims atomic
Andreas-Froyland Sep 7, 2026
c02e2d2
merge: integrate SUP-05A-1 claim assignment
Andreas-Froyland Sep 7, 2026
1a70cb5
chore(support): complete SUP-05A-1
Andreas-Froyland Sep 7, 2026
b411689
feat(support): add per-agent conversation read state
Andreas-Froyland Sep 8, 2026
c9b5f18
fix(support): harden conversation read state races
Andreas-Froyland Sep 8, 2026
53e372f
fix(support): standardize read-state missing conversation error
Andreas-Froyland Sep 8, 2026
d198a00
chore(support): remove misplaced task report
Andreas-Froyland Sep 8, 2026
a570a1d
merge: integrate SUP-05A-2 read state
Andreas-Froyland Sep 8, 2026
2fee359
chore(support): complete SUP-05A-2
Andreas-Froyland Sep 8, 2026
f8ea7c1
feat(support): add fixed inbox views
Andreas-Froyland Sep 8, 2026
5da3d57
test(support): cover fixed view review cases
Andreas-Froyland Sep 8, 2026
b7ecf4b
merge: integrate SUP-05A-3 fixed views
Andreas-Froyland Sep 8, 2026
9960b58
chore(support): complete SUP-05A-3
Andreas-Froyland Sep 8, 2026
8ae0c2f
feat(support): persist local conversation drafts
Andreas-Froyland Sep 8, 2026
716928c
fix(support): clear submitted draft after stale send
Andreas-Froyland Sep 9, 2026
96faf33
merge: integrate SUP-05A-4 local drafts
Andreas-Froyland Sep 9, 2026
f6cf346
chore(support): complete SUP-05A-4
Andreas-Froyland Sep 9, 2026
e85e0ee
feat(support): add team canned responses
Andreas-Froyland Sep 13, 2026
0a2194e
merge: integrate SUP-05A-5 canned responses
Andreas-Froyland Sep 13, 2026
3943c07
chore(support): complete SUP-05A-5
Andreas-Froyland Sep 13, 2026
ceb8405
feat(support): add global conversation search
Andreas-Froyland Sep 13, 2026
26d218a
merge: integrate SUP-05A-6 global search
Andreas-Froyland Sep 13, 2026
d07ecef
chore(support): complete SUP-05A-6
Andreas-Froyland Sep 13, 2026
bcf0255
feat(support): add keyboard shortcuts
Andreas-Froyland Sep 13, 2026
f929fc8
fix(support): stabilize keyboard shortcuts e2e flow
Andreas-Froyland Sep 13, 2026
c461222
merge: integrate SUP-05A-7 keyboard shortcuts
Andreas-Froyland Sep 13, 2026
372ad4e
fix(support): guard shortcut controls and updates
Andreas-Froyland Sep 13, 2026
5161226
merge: integrate SUP-05A-7 shortcut fixes
Andreas-Froyland Sep 13, 2026
e093aff
chore(support): complete SUP-05A-7
Andreas-Froyland Sep 13, 2026
b83019f
docs(support): record SUP-05A-7 brief
Andreas-Froyland Sep 13, 2026
f82a802
docs(support): add SUP-05A-8 brief
Andreas-Froyland Sep 13, 2026
074e635
test(support): add Stage 05A acceptance coverage
Andreas-Froyland Sep 13, 2026
ca892cb
test(support): strengthen Stage 05A acceptance assertions
Andreas-Froyland Sep 13, 2026
22f85bf
merge: integrate SUP-05A-8 acceptance coverage
Andreas-Froyland Sep 13, 2026
9cc51c9
chore(support): complete SUP-05A-8
Andreas-Froyland Sep 13, 2026
b5c79cf
docs(todo): brief SUP-X-3 OpenAPI scanner
Andreas-Froyland Sep 14, 2026
c35e47a
docs(todo): brief SUP-X-6 format gate
Andreas-Froyland Sep 14, 2026
0fbad79
chore(ci): add format check to harness
Andreas-Froyland Sep 14, 2026
7d3ed22
style: normalize files for format gate
Andreas-Froyland Sep 14, 2026
70f1192
merge: integrate SUP-X-6 format gate
Andreas-Froyland Sep 14, 2026
6d5a372
feat(api): generate OpenAPI paths at build time
Andreas-Froyland Sep 14, 2026
03b7de3
merge: integrate SUP-X-3 OpenAPI scanner
Andreas-Froyland Sep 14, 2026
8943e9b
chore(todo): close open cross-cutting items
Andreas-Froyland Sep 14, 2026
97f7575
fix(settings): restrict team module toggles to admins
Andreas-Froyland Sep 14, 2026
f69283a
chore(todo): close SUP-X-4
Andreas-Froyland Sep 14, 2026
2a39ad8
feat(support): ship feedback bridge
Andreas-Froyland Sep 17, 2026
ace5fa5
feat(sla): add business hours foundations
Andreas-Froyland Sep 17, 2026
1d2a2be
feat(sla): match policies when creating conversations
Andreas-Froyland Sep 17, 2026
4daf92e
feat(sla): pause and resume conversation timers
Andreas-Froyland Sep 17, 2026
629aac2
feat(sla): add idempotent breach sweeper
Andreas-Froyland Sep 17, 2026
3597dee
feat(sla): expose countdowns and breaching view
Andreas-Froyland Sep 17, 2026
669ff68
feat(sla): add team SLA settings
Andreas-Froyland Sep 17, 2026
d3e68d4
fix(sla): keep thread countdown helpers as methods
Andreas-Froyland Sep 17, 2026
f82ea9d
docs(sla): mark stage 06 complete
Andreas-Froyland Sep 17, 2026
82b3b4c
feat(automation): add rule schema and condition evaluator
Andreas-Froyland Sep 17, 2026
d71b4c8
feat(automation): isolate action execution failures
Andreas-Froyland Sep 17, 2026
19e8b6e
feat(automation): evaluate rules after support events
Andreas-Froyland Sep 17, 2026
e6afae3
feat(automation): schedule time-based rule evaluation
Andreas-Froyland Sep 17, 2026
698ae58
feat(automation): add rule management surfaces
Andreas-Froyland Sep 17, 2026
214127b
feat(csat): add durable survey dispatch
Andreas-Froyland Sep 17, 2026
69a662c
feat(csat): add public response flow
Andreas-Froyland Sep 17, 2026
d88eda0
feat(csat): add survey configuration
Andreas-Froyland Sep 17, 2026
b7d79d0
feat(csat): add live score surfaces
Andreas-Froyland Sep 17, 2026
9884c76
feat(reporting): add daily metric foundation
Andreas-Froyland Sep 18, 2026
39de1fe
feat(reporting): record conversation status events
Andreas-Froyland Sep 18, 2026
0bd04ff
test(reporting): cover status event transaction wiring
Andreas-Froyland Sep 18, 2026
2eaf999
docs(reporting): record status event slice
Andreas-Froyland Sep 18, 2026
02d5553
feat(reporting): close status event write paths
Andreas-Froyland Sep 18, 2026
c97769e
docs(reporting): close status event coverage
Andreas-Froyland Sep 18, 2026
f20f009
docs(reporting): record status event verification
Andreas-Froyland Sep 18, 2026
c74ff2b
fix(reporting): harden csat summary scope
Andreas-Froyland Sep 18, 2026
88d4b4f
fix(reporting): constrain csat inbox ownership
Andreas-Froyland Sep 18, 2026
f596c36
docs(reporting): record csat hardening
Andreas-Froyland Sep 18, 2026
cc37da1
feat(reporting): persist timezone and csat scale semantics
Andreas-Froyland Sep 18, 2026
1aa94da
docs(reporting): record semantics contract
Andreas-Froyland Sep 18, 2026
e9d9e2f
docs(reporting): clean plan prose
Andreas-Froyland Sep 18, 2026
afeaba7
merge: resolve main into support-platform
Andreas-Froyland Sep 18, 2026
d5282dd
test(build): cover domain backfill lifecycle
Andreas-Froyland Sep 18, 2026
99f3a33
fix(review): address PR findings and CI runtime
Andreas-Froyland Sep 18, 2026
1288dab
ci: resolve Neon branch URL within e2e job
Andreas-Froyland Sep 18, 2026
adc9ba8
ci: configure upload token for e2e server
Andreas-Froyland Sep 18, 2026
acb0863
test(e2e): click product heading for settings navigation
Andreas-Froyland Sep 18, 2026
ac0ca40
test(e2e): assert product card destination
Andreas-Froyland Sep 18, 2026
af053ea
fix(feedback): restore table sort filter
Andreas-Froyland Sep 18, 2026
d665359
test(e2e): allow time for hosted feedback workflow
Andreas-Froyland Sep 18, 2026
301153c
fix(review): address PR runtime and deployment findings
Andreas-Froyland Sep 18, 2026
2823cd2
fix(review): address latest hosted feedback findings
Andreas-Froyland Sep 18, 2026
cd1ce85
test(feedback): stabilize comment edit workflow
Andreas-Froyland Sep 18, 2026
2502290
fix(review): close Cubic runtime and deployment findings
Andreas-Froyland Sep 18, 2026
499eefb
test(e2e): isolate unauthenticated upload request
Andreas-Froyland Sep 18, 2026
f794a4e
test(e2e): use exact feedback back button locator
Andreas-Froyland Sep 18, 2026
1a3e531
test(e2e): stabilize multi-step feedback navigation
Andreas-Froyland Sep 18, 2026
16d1f31
test(e2e): wait for created product before rendering
Andreas-Froyland Sep 18, 2026
256ac6c
test(e2e): await browser product data before rendering
Andreas-Froyland Sep 18, 2026
7e59af0
test(e2e): use exact single-product back locator
Andreas-Froyland Sep 18, 2026
3e31e8e
fix(domains): activate localhost custom domains
Andreas-Froyland Sep 18, 2026
85ff625
test(seed): enable roadmap for demo project
Andreas-Froyland Sep 18, 2026
e8ac472
test(e2e): configure roadmap navigation fixture
Andreas-Froyland Sep 18, 2026
aa88f65
test(e2e): fix anonymous vote count locator
Andreas-Froyland Sep 18, 2026
1659e88
test(e2e): isolate public feedback rate limits
Andreas-Froyland Sep 18, 2026
b99c0e0
test(e2e): preserve public-host auth cookies
Andreas-Froyland Sep 18, 2026
df88835
fix(auth): use host-only cookies for local subdomains
Andreas-Froyland Sep 19, 2026
69b44fd
fix(auth): hand off local cross-host redirects
Andreas-Froyland Sep 19, 2026
bd1e382
fix(public): label feedback details dialog
Andreas-Froyland Sep 19, 2026
96e5ef6
test(e2e): configure GitHub OAuth fixtures
Andreas-Froyland Sep 19, 2026
0c0c30b
test(e2e): track breaching conversation view
Andreas-Froyland Sep 19, 2026
7e0a9ab
test(e2e): disable Nuxt devtools in Playwright server
Andreas-Froyland Sep 19, 2026
3c8faf0
test(e2e): wait for onboarding hydration
Andreas-Froyland Sep 19, 2026
82ab769
test(e2e): wait for products hydration
Andreas-Froyland Sep 19, 2026
e7963df
test(e2e): use preview server in CI
Andreas-Froyland Sep 19, 2026
1c39ad2
test(e2e): accept secure Better Auth cookies
Andreas-Froyland Sep 19, 2026
cf4eeee
test(e2e): allow cold preview startup
Andreas-Froyland Sep 19, 2026
b19b7eb
test(e2e): wait for login controls to hydrate
Andreas-Froyland Sep 19, 2026
07d71dd
test(e2e): avoid private Vue hydration probes
Andreas-Froyland Sep 19, 2026
ac164a5
test(e2e): wait for onboarding hydration
Andreas-Froyland Sep 19, 2026
094a67b
test(e2e): wait for products hydration
Andreas-Froyland Sep 19, 2026
c594e5d
test(e2e): target product dialog heading
Andreas-Froyland Sep 19, 2026
f21a504
test(e2e): wait for settings hydration
Andreas-Froyland Sep 19, 2026
c831565
fix(reporting): harden csat window and feedback sorting
Andreas-Froyland Sep 19, 2026
cec1b8d
fix(realtime): harden reconnect and shared rate limit clients
Andreas-Froyland Sep 19, 2026
8bb6ed0
fix(security): harden domain and webhook guards
Andreas-Froyland Sep 19, 2026
14fbb87
fix(review): harden public privacy and deployment guards
Andreas-Froyland Sep 19, 2026
a020160
fix(review): close latest cubic findings
Andreas-Froyland Sep 19, 2026
d57f581
fix(review): validate Redis integration schemes
Andreas-Froyland Sep 19, 2026
a975e4d
test(e2e): establish workspace for settings tabs
Andreas-Froyland Sep 19, 2026
b5c5714
test(e2e): reflect beta billing visibility
Andreas-Froyland Sep 19, 2026
6dcbc9e
test(e2e): allow sidebar active team lookup
Andreas-Froyland Sep 19, 2026
ba79a12
fix(settings): refresh team panel after sidebar switches
Andreas-Froyland Sep 19, 2026
733a898
fix(settings): refresh organization on team replay
Andreas-Froyland Sep 19, 2026
ea26219
test(e2e): use organization logo removal control
Andreas-Froyland Sep 19, 2026
4d96194
test(e2e): assert organization logo removal
Andreas-Froyland Sep 19, 2026
a23eac2
test(e2e): target product settings headings
Andreas-Froyland Sep 19, 2026
2c1572d
test(e2e): reload product settings deep links
Andreas-Froyland Sep 19, 2026
a22f49e
test(e2e): wait for sidebar hydration before resizing
Andreas-Froyland Sep 19, 2026
feb0c2d
test(e2e): seed deterministic sidebar width
Andreas-Froyland Sep 19, 2026
5e0fbe1
test(e2e): wait for sidebar resize hydration
Andreas-Froyland Sep 19, 2026
81d3869
fix(ui): keep sidebar resize handle above rail
Andreas-Froyland Sep 19, 2026
2507d61
test(e2e): reuse page request authentication
Andreas-Froyland Sep 19, 2026
3ec57cd
test(e2e): use configured Playwright base URL
Andreas-Froyland Sep 19, 2026
2b7ac48
fix(support): reconcile drafts after delayed sends
Andreas-Froyland Sep 19, 2026
ba53bbf
test(e2e): allow time for support flow setup
Andreas-Froyland Sep 19, 2026
d00ceb4
test(e2e): use anonymous requests for public feedback
Andreas-Froyland Sep 19, 2026
5246edf
test(e2e): reuse page authentication for attachment flow
Andreas-Froyland Sep 19, 2026
f833a73
fix(products): restore default status workflow guidance
Andreas-Froyland Sep 19, 2026
14a5c54
test(e2e): allow Neon claim fixture latency
Andreas-Froyland Sep 19, 2026
9054bd5
test(e2e): gate proxy upload phase assertion
Andreas-Froyland Sep 19, 2026
7e7959e
test(e2e): bound proxy upload wait
Andreas-Froyland Sep 19, 2026
976bcad
test(e2e): handle claim dialog during click
Andreas-Froyland Sep 19, 2026
291f8f7
test(e2e): allow Neon SLA detail load
Andreas-Froyland Sep 19, 2026
41587d1
test(e2e): phase team switch mock
Andreas-Froyland Sep 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .agents/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Veerify is a feedback management and verification platform built with **Nuxt 3**

### Prerequisites

- Node.js 18+
- Node.js 22.12+
- Yarn
- Docker (for local PostgreSQL + Mailpit)

Expand Down
26 changes: 26 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
node_modules
.output
.data
.nuxt
.nitro
.cache
dist
.git
.github
.vscode
.idea
.fleet
.claude
.agents
.cursor
docs
playwright-report
test-results
tests
*.log
.env
.env.*
!.env.example
.DS_Store
README.md
export-*.csv
81 changes: 81 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ APP_DOMAIN=localhost
# Dashboard domain (used by login/signup links from public boards)
# Defaults to app.<APP_DOMAIN> when omitted in non-local environments.
APP_DASHBOARD_DOMAIN=localhost
# Optional public URL used in outbound CSAT rating links. Set this to the
# customer-facing HTTPS origin in production; it must be an absolute URL.
APP_URL= # Optional public origin; leave empty to fall back to BETTER_AUTH_URL
# Optional: "self-hosted" or "cloud". When omitted, auto-detected from platform env vars.
APP_DEPLOYMENT_MODE=self-hosted
# Optional, development only. Comma-separated extra Host headers the Vite dev server
# will accept, for reaching `yarn dev` through an HTTPS reverse proxy such as
# Tailscale Serve. Leave empty unless you use one. Example: dev.my-tailnet.ts.net
NUXT_DEV_ALLOWED_HOSTS=

# CNAME target for custom domain setup (point users' CNAMEs here)
CNAME_TARGET=cname.veerify.io
Expand All @@ -44,6 +51,46 @@ VERCEL_PROJECT_ID=
VERCEL_TEAM_ID=
VERCEL_TEAM_SLUG=

# Inbound support email provider. Webhook-only: there is no IMAP polling
# (delta D-29). The [provider] segment of /api/support/inbound/[provider]
# selects the driver per request; this names the deployment's default.
SUPPORT_CHANNEL_PROVIDER=postmark

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: In the self-hosted Docker deployment, these support settings never reach the app because docker-compose.yml does not forward any SUPPORT_* variables. Add the provider and credential variables to the app environment, otherwise configured Postmark or Mailgun webhooks are rejected.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .env.example, line 54:

<comment>In the self-hosted Docker deployment, these support settings never reach the app because `docker-compose.yml` does not forward any `SUPPORT_*` variables. Add the provider and credential variables to the app environment, otherwise configured Postmark or Mailgun webhooks are rejected.</comment>

<file context>
@@ -44,6 +48,46 @@ VERCEL_PROJECT_ID=
+# Inbound support email provider. Webhook-only: there is no IMAP polling
+# (delta D-29). The [provider] segment of /api/support/inbound/[provider]
+# selects the driver per request; this names the deployment's default.
+SUPPORT_CHANNEL_PROVIDER=postmark
+
+# Postmark does NOT sign inbound webhooks - its documented protection is HTTP
</file context>


# Postmark does NOT sign inbound webhooks - its documented protection is HTTP
# Basic Auth in the webhook URL plus IP allowlisting. Set both, then register
# https://user:password@your-host/api/support/inbound/postmark with Postmark.
# Inbound mail is rejected while these are unset; an empty credential must
# never mean "accept anything".
SUPPORT_POSTMARK_WEBHOOK_USER=
SUPPORT_POSTMARK_WEBHOOK_PASSWORD=

# Required when using Mailgun. This is the webhook signing key (not the API
# key); Mailgun signs HMAC-SHA256(timestamp + token) with it.
SUPPORT_MAILGUN_SIGNING_KEY=

# OPTIONAL, Stage 04. Used only to check whether an inbox's From address sits
# on a domain the provider will actually accept, so /support/settings can warn
# before mail silently fails at send time. Leave unset and the check reports
# "cannot verify" rather than a false warning - nothing else is affected.
#
# Postmark: this is the ACCOUNT token, not a server token. The /domains
# endpoint is account-level and a server token returns 401 there.
SUPPORT_POSTMARK_ACCOUNT_TOKEN=
# Non-secret deployment account identifier persisted with outbound deliveries.
# MUST equal the value the provider reports on its own delivery webhooks, or the
# delivery-correlation fallback can never match: for Postmark that is the numeric
# `ServerID`. The primary correlation path uses our own metadata key and works
# regardless, but the fallback is the only defence when a provider drops that
# metadata on an event. Unverified against a live account - see
# docs/plans/2026-08-11-support-platform/stage-01-04-provider-checklist.md.
SUPPORT_POSTMARK_ACCOUNT_KEY=
# Mailgun: the private API key. Set the base URL only for EU accounts
# (https://api.eu.mailgun.net).
SUPPORT_MAILGUN_API_KEY=
# As above: must equal what Mailgun reports on its webhooks, i.e. the sending domain.
SUPPORT_MAILGUN_ACCOUNT_KEY=
SUPPORT_MAILGUN_API_BASE_URL=


# SMTP Configuration for nodemailer
SMTP_HOST=localhost
Expand Down Expand Up @@ -80,7 +127,41 @@ STORAGE_FORCE_PATH_STYLE=false

# Optional public base URL for storage object links (for CDN/custom host)
STORAGE_PUBLIC_BASE_URL=
# Keep proxy-required unless your S3-compatible target demonstrably enforces
# the signed Content-Length. Accepted value: content-length-enforced.
STORAGE_DIRECT_UPLOAD_CONSTRAINTS=proxy-required

# Upload token signing secret (REQUIRED — generate a random secret, e.g. `openssl rand -base64 32`)
# The server will refuse to start if this is not set.
UPLOAD_TOKEN_SECRET=

# --- Realtime / Redis -------------------------------------------------------
# Redis connection string. Written against the Redis wire protocol, so any
# provider works: Upstash on cloud, or the `valkey` service in docker-compose
# when self-hosting. Leave empty to run single-instance with in-memory drivers.
# Example: redis://localhost:6379 or rediss://user:pass@host:6379
REDIS_URL=

# Realtime transport driver: `redis` | `memory`.
# Unset infers `redis` when REDIS_URL is set, otherwise `memory`.
# `memory` is single-instance ONLY — events do not cross app instances.
REALTIME_DRIVER=

# Rate limiter backing store: `redis` | `memory`.
# Same inference rule as REALTIME_DRIVER. `memory` does not enforce limits
# across instances. Shares the REDIS_URL connection; adds no extra socket.
RATE_LIMIT_STORE=

# --- Scheduled tasks --------------------------------------------------------
# Shared secret for Vercel Cron HTTP endpoints under /api/cron/*.
# REQUIRED on cloud deployments: the endpoints fail closed, so an unset secret
# means every scheduled task returns 401 and silently never runs.
# Not needed when self-hosting, where Nitro runs tasks in-process.
# Generate with: openssl rand -base64 32
CRON_SECRET=

# --- Self-hosted deployment (docker-compose.yml) -----------------------------
# Public hostname serving uploaded assets through the Caddy reverse proxy.
# Required by docker-compose.yml and the Caddyfile when self-hosting.
# Example: assets.example.com
STORAGE_DOMAIN=
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Shell scripts must keep LF line endings regardless of core.autocrlf so
# they run correctly inside Linux containers (a CRLF shebang breaks `/bin/sh`).
*.sh text eol=lf
Caddyfile text eol=lf
23 changes: 13 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile
Expand All @@ -36,7 +36,7 @@ jobs:

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile
Expand All @@ -53,7 +53,7 @@ jobs:

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile
Expand All @@ -69,15 +69,12 @@ jobs:

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile

# Run nuxt build directly (not `yarn build`) to skip the
# postbuild lifecycle hook, which runs db migrations and
# requires a live PostgreSQL connection.
- run: npx nuxt build
- run: yarn build

e2e:
name: E2E (Playwright)
Expand Down Expand Up @@ -108,13 +105,19 @@ jobs:
PGPASSWORD: veerifypassword
PGDATABASE: veerifydb
BETTER_AUTH_URL: http://localhost:4173
UPLOAD_TOKEN_SECRET: playwright-e2e-upload-secret
# The OAuth test only validates the generated GitHub authorization URL;
# these placeholder credentials keep the provider enabled without using
# a real GitHub application or secret in CI.
GITHUB_CLIENT_ID: playwright-e2e-github-client
GITHUB_CLIENT_SECRET: playwright-e2e-github-secret
PLAYWRIGHT_SKIP_IS_FAILURE: '1'
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile
Expand All @@ -123,7 +126,7 @@ jobs:
run: npx playwright install --with-deps chromium

- name: Run migrations
run: yarn db:migrate
run: yarn db:migrate:deploy

- name: Seed test data
run: yarn db:seed:e2e
Expand Down
35 changes: 30 additions & 5 deletions .github/workflows/neon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
name: Create Neon Branch
outputs:
db_url: ${{ steps.create_neon_branch.outputs.db_url }}
db_url_with_pooler: ${{ steps.create_neon_branch.outputs.db_url_with_pooler }}
db_url_pooled: ${{ steps.create_neon_branch.outputs.db_url_pooled }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Custom agent: Flag AI Slop and Fabricated Changes

After this output rename, the workflow comments still instruct users to consume db_url_with_pooler, but this workflow now exposes db_url_pooled; update both documented references.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/neon.yml, line 29:

<comment>After this output rename, the workflow comments still instruct users to consume `db_url_with_pooler`, but this workflow now exposes `db_url_pooled`; update both documented references.</comment>

<file context>
@@ -26,7 +26,7 @@ jobs:
     outputs:
       db_url: ${{ steps.create_neon_branch.outputs.db_url }}
-      db_url_with_pooler: ${{ steps.create_neon_branch.outputs.db_url_with_pooler }}
+      db_url_pooled: ${{ steps.create_neon_branch.outputs.db_url_pooled }}
     needs: setup
     if: |
</file context>

needs: setup
if: |
github.event_name == 'pull_request' && (
Expand Down Expand Up @@ -57,14 +57,39 @@ jobs:
|| github.event.action == 'reopened')
runs-on: ubuntu-latest
env:
DATABASE_URL: ${{ needs.create_neon_branch.outputs.db_url_with_pooler }}
BETTER_AUTH_URL: http://localhost:4173
UPLOAD_TOKEN_SECRET: playwright-e2e-upload-secret
# The OAuth test only validates the generated GitHub authorization URL;
# these placeholder credentials keep the provider enabled without using
# a real GitHub application or secret in CI.
GITHUB_CLIENT_ID: playwright-e2e-github-client
GITHUB_CLIENT_SECRET: playwright-e2e-github-secret
steps:
- uses: actions/checkout@v4

# Job outputs containing connection strings are treated as secrets by
# GitHub and are not reliably forwarded between jobs. Resolve the
# already-created branch again in this job so its pooled URL is available
# to the migration, seed, and Playwright steps without crossing a job
# boundary.
- name: Resolve Neon branch connection
id: resolve_neon_branch
uses: neondatabase/create-branch-action@v6
with:
project_id: ${{ vars.NEON_PROJECT_ID }}
branch_name: preview/pr-${{ github.event.number }}-${{ needs.setup.outputs.branch }}
api_key: ${{ secrets.NEON_API_KEY }}
role: neondb_owner
database: neondb
ssl: require
suspend_timeout: 0

- name: Export Neon database URL
run: echo "DATABASE_URL=${{ steps.resolve_neon_branch.outputs.db_url_pooled }}" >> "$GITHUB_ENV"

- uses: actions/setup-node@v5
with:
node-version: '20'
node-version: '22'
cache: yarn

- run: yarn install --frozen-lockfile
Expand Down Expand Up @@ -103,15 +128,15 @@ jobs:
# You may want to do something with the new branch, such as run migrations, run tests
# on it, or send the connection details to a hosting platform environment.
# The branch DATABASE_URL is available to you via:
# "${{ steps.create_neon_branch.outputs.db_url_with_pooler }}".
# "${{ steps.create_neon_branch.outputs.db_url_pooled }}".
# It's important you don't log the DATABASE_URL as output as it contains a username and
# password for your database.
# For example, you can uncomment the lines below to run a database migration command:
# - name: Run Migrations
# run: npm run db:migrate
# env:
# # to use pooled connection
# DATABASE_URL: "${{ steps.create_neon_branch.outputs.db_url_with_pooler }}"
# DATABASE_URL: "${{ steps.create_neon_branch.outputs.db_url_pooled }}"
# # OR to use unpooled connection
# # DATABASE_URL: "${{ steps.create_neon_branch.outputs.db_url }}"

Expand Down
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,15 @@ test-results
.env.*
!.env.example
.vercel

# Agent git worktrees (nested checkouts of this repo)
.claude/worktrees/

# Sleekplan/CSV import test exports dropped in the repo root by manual importer runs.
# These contain real customer data (names, email addresses) and must never be committed.
export-*.csv

# Generated SDD review packages: a full `git diff -U10` of a task range, often
# megabytes, and reproducible from history at any time with `review-package`.
# The task reports beside them are hand-written and stay tracked.
.superpowers/sdd/**/review-*.diff
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
dist
.cache
server/database/migrations
server/generated/openapi-routes.ts
3 changes: 2 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"trailingComma": "es5",
"printWidth": 120,
"tabWidth": 2,
"bracketSpacing": true
"bracketSpacing": true,
"endOfLine": "auto"
}
Loading
Loading