commits
This reverts commit e90079b5aa0ef8fb3300ba18e7191b30b2476ed9.
* "Claude PR Assistant workflow"
* "Claude Code Review workflow"
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* only allow claude tagging
---------
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Initial plan
* Add external_name field to Monitor struct in models.go
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add external_name field to Monitor struct in Go models
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Initial plan
* Add GitHub workflow for deploying private-location app
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add explicit permissions to deploy-private-location workflow
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* try loggingsucks
* ci: apply automated fixes
* try loggingsucks
* ci: apply automated fixes
* trying loging sucks
* upgrade logtap
* ci: apply automated fixes
* fix test
* improve logging
* improve logging
* ci: apply automated fixes
* improve logging
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix(docker): update Dockerfile to install curl for health check
* use dofigen
---------
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.com>
* fix(compose): mount expected volume
* fix: invalid file protocol usage
* chore: remove artifact from previous PR - oops!
* chore: include addon in upgrade dialog
* chore: add billing link
* chore: increase opacity
* feat: page components migration
* chore: sync data [to be reverted]
* fix: tsc and transaction
* fix: test location
* fix: missing description
* feat: add copy to CSV button for Checker table
Add functionality to export Checker table data to CSV format for easier
comparison in spreadsheet applications. Includes visual feedback via toast
notifications on success/failure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add timing data (DNS, Connect, TLS, TTFB, Transfer) to CSV export
Extend the CSV export to include detailed timing phases for each region check,
enabling deeper performance analysis in spreadsheet applications.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: change CSV copy to file download export
- Replace clipboard copy with file download functionality
- Add Export to CSV button to checker details page (next to search input)
- Filename includes sanitized URL and date (e.g., checker-example.com-2026-01-15.csv)
- Responsive layout: vertical on mobile, horizontal on desktop
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci: apply automated fixes
* chore: create utils
* fix: escape specific csv values
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat(db): add unsubscribedAt field to page_subscriber schema
Add unsubscribedAt timestamp field to support email unsubscribe feature.
This enables tracking when subscribers opt out of status page notifications.
- Add unsubscribedAt field to page_subscriber table schema
- Create migration 0053 to ALTER TABLE with new column
- Update drizzle journal and snapshot files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add unsubscribe mutation to statusPage router
Add public unsubscribe mutation that allows page subscribers to
unsubscribe from status page notifications. The mutation validates
that the token exists, the subscription is verified, and the user
hasn't already unsubscribed before setting the unsubscribedAt timestamp.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add getSubscriberByToken query to statusPage router
Add public query to retrieve subscriber info for the unsubscribe
confirmation page. Returns page name and masked email for valid
subscribers, or null if not found or already unsubscribed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(server): add RFC 8058 one-click unsubscribe endpoint
Add public POST endpoint at /public/unsubscribe/:token for email clients
that support one-click unsubscribe (RFC 8058). The endpoint validates the
token, checks subscriber status, and sets the unsubscribedAt timestamp.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(emails): add unsubscribe link to status report emails
- Add `unsubscribeUrl` optional prop to StatusReportSchema
- Add footer section with unsubscribe link (conditionally rendered)
- Style footer with small, muted text for visual hierarchy
- Update preview props with sample unsubscribe URL
- Remove old TODO comment
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(emails): add RFC 8058 List-Unsubscribe headers to status report emails
- Update sendStatusReportUpdate to accept subscribers with tokens
- Add List-Unsubscribe and List-Unsubscribe-Post headers per RFC 8058
- Pass unsubscribeUrl to StatusReportEmail template for each subscriber
- Update all callers to pass subscriber tokens instead of just emails
- Filter out subscribers with null tokens for type safety
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(server): filter out unsubscribed users from email notifications
Add isNull(pageSubscriber.unsubscribedAt) to subscriber queries in
statusReports/post.ts and statusReportUpdates/post.ts to ensure
unsubscribed users no longer receive status report emails.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(status-page): add unsubscribe confirmation page
Add a user-facing unsubscribe confirmation page at
/[domain]/unsubscribe/[token] that allows subscribers to
confirm their unsubscription from status page notifications.
Features:
- Loading state while fetching subscriber info
- Error state for invalid/expired tokens
- Confirmation view with masked email and page name
- Success state after unsubscription
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(dashboard): add subscriber status column to table
Add a Status column to the subscribers data table that displays:
- "Active" badge for verified subscribers
- "Pending" badge for unverified subscribers
- "Unsubscribed {date}" badge for users who have unsubscribed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add re-subscription flow for unsubscribed users
When an unsubscribed user attempts to subscribe again:
- Clear unsubscribedAt field
- Reset acceptedAt to require re-verification
- Regenerate token for security
- Update expiresAt for new verification window
Also handles pending (unverified) re-subscription by regenerating token.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(api): add unit tests for unsubscribe API endpoints
Add comprehensive unit tests for getSubscriberByToken query and
unsubscribe mutation in statusPage router:
- Test valid token returns masked email and page name
- Test non-existent token returns null/undefined
- Test already unsubscribed user returns null
- Test email masking logic with various edge cases
- Test unsubscribe mutation success and error scenarios
- Test UUID token format validation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add integration tests for email headers and subscriber filtering
- Add email client integration tests for List-Unsubscribe headers
- Add subscriber filtering integration tests for email queries
- Test RFC 8058 compliance headers (List-Unsubscribe-Post)
- Test email body contains unsubscribe link with proper styling
- Test unsubscribed users are excluded from notification queries
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(api): add E2E tests for full unsubscribe flow
Add comprehensive end-to-end integration tests covering the complete
unsubscribe user journey: subscribe -> verify -> receive email -> unsubscribe.
Tests include:
- Full subscribe/verify/unsubscribe flow with proper state transitions
- Confirmation page displaying correct page name and masked email
- Timestamp tracking when user clicks confirm unsubscribe
- Email recipient filtering to exclude unsubscribed users
- Re-subscription flow after unsubscribe
- Invalid token handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove ralph prd and progress files
* fix: format
* fix: valid subscribers
* fix: sqlite precision time
* refactor: update List-Unsubscribe to redirect to status page
Change the email unsubscribe URL from the API endpoint (/public/unsubscribe)
to the status page's unsubscribe page. This allows users to see a proper
unsubscribe confirmation UI instead of a direct API response.
- Remove List-Unsubscribe-Post header (no longer using one-click POST)
- Update List-Unsubscribe to use status page URL
- Add pageSlug and customDomain params to sendStatusReportUpdate
- Update all call sites to pass page slug/domain info
- Update integration tests for new URL format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Update packages/emails/src/client.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: email header
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: filter expected tRPC errors from Sentry notifications
Mute UNAUTHORIZED (401), NOT_FOUND (404), and BAD_REQUEST (400) errors
to reduce noise from expected client errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: filter expected tRPC errors from Sentry notifications
Mute UNAUTHORIZED (401), NOT_FOUND (404), and BAD_REQUEST (400) errors
to reduce noise from expected client errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* ci: apply automated fixes
* Fix inconsistent TRPCError filtering in status-page edge Sentry config (#1727)
* Initial plan
* fix: use consistent TRPCError filtering in status-page edge config
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* feat: ralph
* fix: redirect to /status-pages when user has no access to page id
Instead of throwing an error when a user navigates to /status-pages/[id]
without access, we now gracefully redirect them to the status pages list.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove try/catch
* ci: apply automated fixes
* fix: typos
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* custom api key
* phase 2
* implment phase 3
* implment phase 4
* implement phase 5
* implement phase 6
* format
* fix build
* ci: apply automated fixes
* fixing stuff
* ci: apply automated fixes
* fix test
* fmt
* use react-hook-form
* ci: apply automated fixes
* improve pr
* improve pr
* improve db
* fix: ui
* fix: truncate text
* fix: copy button
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
* feat: Add automatic DB migrations for Docker deployments
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* feat: Remove separate service for DB migrations
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* fix: Update React package to resolve version mismatch
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* feat: Simplify DB seeding
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* Update pnpm-lock.yaml
---------
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.com>
* remove dead code
* ci: apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* add some test
* ci: apply automated fixes
* why?
* ci: apply automated fixes
* fix test
* ci: apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Initial plan
* Add test files for missing API endpoints
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix import ordering in test files
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add test cases with different payloads for each endpoint
- Add TCP monitor tests for run and trigger endpoints
- Add multiple region tests for run and trigger endpoints
- Add different status tests for status report updates
- Add result validation tests for monitor results endpoint
- Total: 8 new test cases across 4 test files
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add 11 test cases with different payloads to post_tcp.test.ts
- Test different ports (80, 443, 8080)
- Test different frequencies (30s, 1m, 5m, 10m, 30m, 1h)
- Test with/without optional fields (timeout, retry, degradedAfter, description)
- Test OpenTelemetry configuration
- Test multiple regions
- Test public/private monitors
- Test active/inactive monitors
- Test invalid host and port
- Test deprecated regions
- Total: 14 test cases (was 3, added 11)
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add test cases with different payloads to post_http and statusReportUpdates
HTTP Monitor Tests (post_http.test.ts):
- Different HTTP methods: GET, PUT, PATCH, DELETE
- Different frequencies: 30s, 1h
- Different assertion types: textBody, multiple assertions
- Configuration variants: timeout, retry, degradedAfter
- OpenTelemetry configuration with custom headers
- Minimal payload (only required fields)
- Invalid URL and deprecated regions validation
Total: 16 test cases (was 3, added 13)
Status Report Update Tests (post.test.ts):
- All status types: investigating, identified, monitoring, resolved
- With/without explicit date (testing defaults)
- Past dates and long messages
- Different status report IDs
- Invalid payloads: invalid status, missing message, missing statusReportId, empty message
Total: 14 test cases (was 3, added 11)
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix date manipulation in statusReportUpdates test
Use explicit time subtraction instead of setDate for clearer 24-hour subtraction
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix empty message validation in StatusReportUpdate schema (#1703)
* Initial plan
* Fix validation issues in statusReportUpdates schema and deprecated endpoint
- Add .min(1) validation to message field to reject empty messages
- Fix deprecated endpoint schema to omit statusReportId from request body
- Fix deprecated endpoint to return correct StatusReport schema
- Fix test to use correct workspace for cross-workspace access check
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Remove redundant database update in deprecated endpoint
- Consolidate status and updatedAt updates into single query
- Remove duplicate update operation that was updating the same fields
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* ci: apply automated fixes
* fix test
* ci: apply automated fixes
* fixing test
* fix test
* ci: apply automated fixes
* add more test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* Initial plan
* Improve docs structure with Diátaxis framework
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Enhance tutorials, guides, and explanations with better structure
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Improve CLI tutorial and monitoring-as-code explanation
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Enhance reference docs and GitHub Actions guide
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* fix docs
* remove old docs
* remove emdash
* more docs
* improve reference part
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* chore: introducing status page addons
* chore: blog and changelogs
* fix: typo
* fix: images
* Initial plan
* Add White Label section to status page reference documentation
Co-authored-by: mxkaske <56969857+mxkaske@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mxkaske <56969857+mxkaske@users.noreply.github.com>
* wip: quantity addons
* refactor: quantiy selector in modal
* wip: stripe quantity
* fix: spacing
* fix: default value
* page add on
* ci: apply automated fixes
---------
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Initial plan
* Upgrade all @react-email dependencies to latest versions
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* add white label status page
* small changes
* fixing build
* ci: apply automated fixes
* chore: white-label
* fix build
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
* update oxc-lint
* ci: apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix: url protocol error
* chore: error message
* wip: statuspage magic link
* fix: build
* fix: comments
* fix: package.json
* wip: user without workspace
* wip: dashboard form
* wip: magic link
* chore: access type email-domain
* wip: review
* chore: pricing table and addon button
* ci: apply automated fixes
* fix: zod 4 schema
* Add stripe product
* ci: apply automated fixes
* refactor: auth and migration
* fix: web build
* chore: add success check if addon exists
* Add stripe product
improve subscription
* fix
* ci: apply automated fixes
* update
* ci: apply automated fixes
* fix: addon pricing
* refactor: duplication
* fix: number format
* chore: enforce plan limit addons to be false
* wip: addon
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* 😭
* 😭
* ci: apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix zod migration
* Revert "Migrate zod v3 to v4 (#1592)" (#1686)
This reverts commit 4cd9e153049a35998a4858c8cfcef323635e80c0.
* fix zod
* ci: apply automated fixes
* fixing build
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This reverts commit 4cd9e153049a35998a4858c8cfcef323635e80c0.
* fix: duplicate verification email
* Updated dashboard tsconfig
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Status page migrated zod
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Migrated web tsconfig.json
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update zod v4 migration
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update default to prefault
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Updated zod to v4
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update zod deprecated
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* ci: apply automated fixes
* Updated some packages for server and test
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Updated the errors for invalid union
* Remove unused redis from page
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* update pnpmlock
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update the monitor schema
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* ci: apply automated fixes
* Updated the typeerror coming from application
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update the type error in dashboard
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Migrated to zod and updated to latest
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* fix: workspace limit validation
* chore: improve types
* ci: apply automated fixes
* fix: react-hook-form zod resolver
* fix: url zod notification
---------
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* "Claude PR Assistant workflow"
* "Claude Code Review workflow"
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* only allow claude tagging
---------
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Initial plan
* Add external_name field to Monitor struct in models.go
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add external_name field to Monitor struct in Go models
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Initial plan
* Add GitHub workflow for deploying private-location app
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add explicit permissions to deploy-private-location workflow
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* try loggingsucks
* ci: apply automated fixes
* try loggingsucks
* ci: apply automated fixes
* trying loging sucks
* upgrade logtap
* ci: apply automated fixes
* fix test
* improve logging
* improve logging
* ci: apply automated fixes
* improve logging
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat: add copy to CSV button for Checker table
Add functionality to export Checker table data to CSV format for easier
comparison in spreadsheet applications. Includes visual feedback via toast
notifications on success/failure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add timing data (DNS, Connect, TLS, TTFB, Transfer) to CSV export
Extend the CSV export to include detailed timing phases for each region check,
enabling deeper performance analysis in spreadsheet applications.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: change CSV copy to file download export
- Replace clipboard copy with file download functionality
- Add Export to CSV button to checker details page (next to search input)
- Filename includes sanitized URL and date (e.g., checker-example.com-2026-01-15.csv)
- Responsive layout: vertical on mobile, horizontal on desktop
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci: apply automated fixes
* chore: create utils
* fix: escape specific csv values
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* feat(db): add unsubscribedAt field to page_subscriber schema
Add unsubscribedAt timestamp field to support email unsubscribe feature.
This enables tracking when subscribers opt out of status page notifications.
- Add unsubscribedAt field to page_subscriber table schema
- Create migration 0053 to ALTER TABLE with new column
- Update drizzle journal and snapshot files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add unsubscribe mutation to statusPage router
Add public unsubscribe mutation that allows page subscribers to
unsubscribe from status page notifications. The mutation validates
that the token exists, the subscription is verified, and the user
hasn't already unsubscribed before setting the unsubscribedAt timestamp.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add getSubscriberByToken query to statusPage router
Add public query to retrieve subscriber info for the unsubscribe
confirmation page. Returns page name and masked email for valid
subscribers, or null if not found or already unsubscribed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(server): add RFC 8058 one-click unsubscribe endpoint
Add public POST endpoint at /public/unsubscribe/:token for email clients
that support one-click unsubscribe (RFC 8058). The endpoint validates the
token, checks subscriber status, and sets the unsubscribedAt timestamp.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(emails): add unsubscribe link to status report emails
- Add `unsubscribeUrl` optional prop to StatusReportSchema
- Add footer section with unsubscribe link (conditionally rendered)
- Style footer with small, muted text for visual hierarchy
- Update preview props with sample unsubscribe URL
- Remove old TODO comment
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(emails): add RFC 8058 List-Unsubscribe headers to status report emails
- Update sendStatusReportUpdate to accept subscribers with tokens
- Add List-Unsubscribe and List-Unsubscribe-Post headers per RFC 8058
- Pass unsubscribeUrl to StatusReportEmail template for each subscriber
- Update all callers to pass subscriber tokens instead of just emails
- Filter out subscribers with null tokens for type safety
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(server): filter out unsubscribed users from email notifications
Add isNull(pageSubscriber.unsubscribedAt) to subscriber queries in
statusReports/post.ts and statusReportUpdates/post.ts to ensure
unsubscribed users no longer receive status report emails.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(status-page): add unsubscribe confirmation page
Add a user-facing unsubscribe confirmation page at
/[domain]/unsubscribe/[token] that allows subscribers to
confirm their unsubscription from status page notifications.
Features:
- Loading state while fetching subscriber info
- Error state for invalid/expired tokens
- Confirmation view with masked email and page name
- Success state after unsubscription
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(dashboard): add subscriber status column to table
Add a Status column to the subscribers data table that displays:
- "Active" badge for verified subscribers
- "Pending" badge for unverified subscribers
- "Unsubscribed {date}" badge for users who have unsubscribed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(api): add re-subscription flow for unsubscribed users
When an unsubscribed user attempts to subscribe again:
- Clear unsubscribedAt field
- Reset acceptedAt to require re-verification
- Regenerate token for security
- Update expiresAt for new verification window
Also handles pending (unverified) re-subscription by regenerating token.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(api): add unit tests for unsubscribe API endpoints
Add comprehensive unit tests for getSubscriberByToken query and
unsubscribe mutation in statusPage router:
- Test valid token returns masked email and page name
- Test non-existent token returns null/undefined
- Test already unsubscribed user returns null
- Test email masking logic with various edge cases
- Test unsubscribe mutation success and error scenarios
- Test UUID token format validation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add integration tests for email headers and subscriber filtering
- Add email client integration tests for List-Unsubscribe headers
- Add subscriber filtering integration tests for email queries
- Test RFC 8058 compliance headers (List-Unsubscribe-Post)
- Test email body contains unsubscribe link with proper styling
- Test unsubscribed users are excluded from notification queries
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(api): add E2E tests for full unsubscribe flow
Add comprehensive end-to-end integration tests covering the complete
unsubscribe user journey: subscribe -> verify -> receive email -> unsubscribe.
Tests include:
- Full subscribe/verify/unsubscribe flow with proper state transitions
- Confirmation page displaying correct page name and masked email
- Timestamp tracking when user clicks confirm unsubscribe
- Email recipient filtering to exclude unsubscribed users
- Re-subscription flow after unsubscribe
- Invalid token handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove ralph prd and progress files
* fix: format
* fix: valid subscribers
* fix: sqlite precision time
* refactor: update List-Unsubscribe to redirect to status page
Change the email unsubscribe URL from the API endpoint (/public/unsubscribe)
to the status page's unsubscribe page. This allows users to see a proper
unsubscribe confirmation UI instead of a direct API response.
- Remove List-Unsubscribe-Post header (no longer using one-click POST)
- Update List-Unsubscribe to use status page URL
- Add pageSlug and customDomain params to sendStatusReportUpdate
- Update all call sites to pass page slug/domain info
- Update integration tests for new URL format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Update packages/emails/src/client.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: email header
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: filter expected tRPC errors from Sentry notifications
Mute UNAUTHORIZED (401), NOT_FOUND (404), and BAD_REQUEST (400) errors
to reduce noise from expected client errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: filter expected tRPC errors from Sentry notifications
Mute UNAUTHORIZED (401), NOT_FOUND (404), and BAD_REQUEST (400) errors
to reduce noise from expected client errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* ci: apply automated fixes
* Fix inconsistent TRPCError filtering in status-page edge Sentry config (#1727)
* Initial plan
* fix: use consistent TRPCError filtering in status-page edge config
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* feat: ralph
* fix: redirect to /status-pages when user has no access to page id
Instead of throwing an error when a user navigates to /status-pages/[id]
without access, we now gracefully redirect them to the status pages list.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: remove try/catch
* ci: apply automated fixes
* fix: typos
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* custom api key
* phase 2
* implment phase 3
* implment phase 4
* implement phase 5
* implement phase 6
* format
* fix build
* ci: apply automated fixes
* fixing stuff
* ci: apply automated fixes
* fix test
* fmt
* use react-hook-form
* ci: apply automated fixes
* improve pr
* improve pr
* improve db
* fix: ui
* fix: truncate text
* fix: copy button
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
* feat: Add automatic DB migrations for Docker deployments
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* feat: Remove separate service for DB migrations
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* fix: Update React package to resolve version mismatch
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* feat: Simplify DB seeding
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
* Update pnpm-lock.yaml
---------
Signed-off-by: Ramtin Mesgari <26694963+iamramtin@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.com>
* Initial plan
* Add test files for missing API endpoints
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix import ordering in test files
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add test cases with different payloads for each endpoint
- Add TCP monitor tests for run and trigger endpoints
- Add multiple region tests for run and trigger endpoints
- Add different status tests for status report updates
- Add result validation tests for monitor results endpoint
- Total: 8 new test cases across 4 test files
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add 11 test cases with different payloads to post_tcp.test.ts
- Test different ports (80, 443, 8080)
- Test different frequencies (30s, 1m, 5m, 10m, 30m, 1h)
- Test with/without optional fields (timeout, retry, degradedAfter, description)
- Test OpenTelemetry configuration
- Test multiple regions
- Test public/private monitors
- Test active/inactive monitors
- Test invalid host and port
- Test deprecated regions
- Total: 14 test cases (was 3, added 11)
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Add test cases with different payloads to post_http and statusReportUpdates
HTTP Monitor Tests (post_http.test.ts):
- Different HTTP methods: GET, PUT, PATCH, DELETE
- Different frequencies: 30s, 1h
- Different assertion types: textBody, multiple assertions
- Configuration variants: timeout, retry, degradedAfter
- OpenTelemetry configuration with custom headers
- Minimal payload (only required fields)
- Invalid URL and deprecated regions validation
Total: 16 test cases (was 3, added 13)
Status Report Update Tests (post.test.ts):
- All status types: investigating, identified, monitoring, resolved
- With/without explicit date (testing defaults)
- Past dates and long messages
- Different status report IDs
- Invalid payloads: invalid status, missing message, missing statusReportId, empty message
Total: 14 test cases (was 3, added 11)
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix date manipulation in statusReportUpdates test
Use explicit time subtraction instead of setDate for clearer 24-hour subtraction
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Fix empty message validation in StatusReportUpdate schema (#1703)
* Initial plan
* Fix validation issues in statusReportUpdates schema and deprecated endpoint
- Add .min(1) validation to message field to reject empty messages
- Fix deprecated endpoint schema to omit statusReportId from request body
- Fix deprecated endpoint to return correct StatusReport schema
- Fix test to use correct workspace for cross-workspace access check
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Remove redundant database update in deprecated endpoint
- Consolidate status and updatedAt updates into single query
- Remove duplicate update operation that was updating the same fields
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* ci: apply automated fixes
* fix test
* ci: apply automated fixes
* fixing test
* fix test
* ci: apply automated fixes
* add more test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
* todo test
* ci: apply automated fixes
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* Initial plan
* Improve docs structure with Diátaxis framework
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Enhance tutorials, guides, and explanations with better structure
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Improve CLI tutorial and monitoring-as-code explanation
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* Enhance reference docs and GitHub Actions guide
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* fix docs
* remove old docs
* remove emdash
* more docs
* improve reference part
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* Initial plan
* Add White Label section to status page reference documentation
Co-authored-by: mxkaske <56969857+mxkaske@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mxkaske <56969857+mxkaske@users.noreply.github.com>
* wip: quantity addons
* refactor: quantiy selector in modal
* wip: stripe quantity
* fix: spacing
* fix: default value
* page add on
* ci: apply automated fixes
---------
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Initial plan
* Upgrade all @react-email dependencies to latest versions
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thibaultleouay <13894054+thibaultleouay@users.noreply.github.com>
* wip: statuspage magic link
* fix: build
* fix: comments
* fix: package.json
* wip: user without workspace
* wip: dashboard form
* wip: magic link
* chore: access type email-domain
* wip: review
* chore: pricing table and addon button
* ci: apply automated fixes
* fix: zod 4 schema
* Add stripe product
* ci: apply automated fixes
* refactor: auth and migration
* fix: web build
* chore: add success check if addon exists
* Add stripe product
improve subscription
* fix
* ci: apply automated fixes
* update
* ci: apply automated fixes
* fix: addon pricing
* refactor: duplication
* fix: number format
* chore: enforce plan limit addons to be false
* wip: addon
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Thibault Le Ouay Ducasse <thibaultleouay@gmail.com>
* fix: duplicate verification email
* Updated dashboard tsconfig
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Status page migrated zod
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Migrated web tsconfig.json
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update zod v4 migration
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update default to prefault
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Updated zod to v4
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update zod deprecated
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* ci: apply automated fixes
* Updated some packages for server and test
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Updated the errors for invalid union
* Remove unused redis from page
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* update pnpmlock
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update the monitor schema
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* ci: apply automated fixes
* Updated the typeerror coming from application
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Update the type error in dashboard
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* Migrated to zod and updated to latest
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
* fix: workspace limit validation
* chore: improve types
* ci: apply automated fixes
* fix: react-hook-form zod resolver
* fix: url zod notification
---------
Signed-off-by: Moulik Aggarwal <qwertymoulik@gmail.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>