fix(deploy): reuse shared redis and serve dashboard at root

This commit is contained in:
2026-08-23 17:32:02 +08:00
parent 56a2f2e6a5
commit 25ef9ae494
17 changed files with 105 additions and 121 deletions
+6 -5
View File
@@ -10,9 +10,9 @@ Production web and worker processes never migrate on startup. The Compose file
also requires `GOCHAT_IMAGE_REF` to be an immutable `image@sha256:digest`; tags such
as `latest` are not an acceptable rollback record.
The bundled `gochat_storage` volume is shared and durable for replicas on one
Docker host. Multi-host replicas must provision that volume with a shared
volume driver/filesystem; never use separate node-local volumes.
Persistent files live under `deploy/docker/data/` beside the production Compose
file. Multi-host replicas must mount shared storage at that path; never use
separate node-local attachment directories.
## Recovery objectives
@@ -40,7 +40,7 @@ export GOCHAT_CONNECTOR_BACKUP_NAME="connector-$(date -u +%Y%m%dT%H%M%SZ).db"
```
Backup/restore are audited one-shot containers and run as root only to read or
rebuild Docker volumes; web and worker remain non-root.
rebuild bind-mounted data directories; web and worker remain non-root.
For an external database using certificate files, keep the three DSN paths
fixed as documented in `.env.example`. Set the host files' group to
`GOCHAT_DATABASE_TLS_GID` and grant that group read permission (`0640` for the
@@ -67,7 +67,8 @@ off-site copy exits non-zero and must alert.
## Clean-environment restore rehearsal
Use an isolated host/project with empty volumes and an empty PostgreSQL database.
Use an isolated host/project with an empty `deploy/docker/data/` directory and
an empty PostgreSQL database.
Do not point this procedure at the live project.
```bash
+2 -2
View File
@@ -5,10 +5,10 @@ All commands run from the repository root. Set `COMPOSE='docker compose -f deplo
## Install and preflight
- **Owner:** release engineer; SRE on-call approves the target host.
- **Prerequisites:** Docker Compose 2.26+, immutable GoChat/Connector digests, external backup mount, untracked backup passphrase and Alertmanager HTTPS webhook files. For external PostgreSQL, set one complete `GOCHAT_DATABASE_DSN` with exactly one `sslmode=verify-ca|verify-full`. When using a private CA or client certificate, keep the DSN paths fixed at `/run/secrets/external-db-ca.crt`, `/run/secrets/external-db-client.crt`, and `/run/secrets/external-db-client.key`; set the three corresponding untracked host-file variables plus `GOCHAT_DATABASE_TLS_GID`, assign that group to the files, and grant group read permission (`0640` for the key). Compose mounts the files read-only and adds the group to every database client.
- **Prerequisites:** Docker Compose 2.26+, immutable GoChat/Connector digests, external backup mount, untracked backup passphrase and Alertmanager HTTPS webhook files. Create the required `deploy/docker/data/` subdirectories before startup. For external PostgreSQL, set one complete `GOCHAT_DATABASE_DSN` with exactly one `sslmode`: use `disable` only on a trusted private network, or use `verify-ca`/`verify-full` for TLS. Redis may use unauthenticated `redis://` only on a trusted private Docker network; use authenticated `rediss://` when traffic crosses an untrusted network. When PostgreSQL uses a private CA or client certificate, keep the DSN paths fixed at `/run/secrets/external-db-ca.crt`, `/run/secrets/external-db-client.crt`, and `/run/secrets/external-db-client.key`; set the three corresponding untracked host-file variables plus `GOCHAT_DATABASE_TLS_GID`, assign that group to the files, and grant group read permission (`0640` for the key). Compose mounts the files read-only and adds the group to every database client.
- **Commands:** `deploy/docker/preflight.sh .env`; then `$COMPOSE config --quiet`; then `$COMPOSE --profile ops run --rm migrate`; finally `$COMPOSE up -d --wait`.
- **Success / failure:** success means preflight exits 0, every non-profile service is healthy/running, and rendered `gochat`, `migrate`, `backup`, `restore`, and `postgres-exporter` configuration uses the same database DSN; any mutable image, missing secret file, DSN mismatch, migration error, or unhealthy service is failure.
- **Rollback:** `$COMPOSE down` leaves named data volumes intact; if migration ran, follow `01-rolling-upgrade.md` and restore the preflight backup instead of running schema down.
- **Rollback:** `$COMPOSE down` leaves `deploy/docker/data/` intact; if migration ran, follow `01-rolling-upgrade.md` and restore the preflight backup instead of running schema down.
- **Drill cadence:** before every release and quarterly on a clean host.
## TLS and reverse proxy
+1 -1
View File
@@ -1,6 +1,6 @@
# Chatwoot Route Source Declarations
Source: `docs/chatwoot/config/routes.rb`
Source: `../docs/chatwoot/config/routes.rb`
Ruby is unavailable in the current workspace, so this file records static route DSL declarations with source lines. It is a repeatable fallback until `bin/rails routes` can run.
+25 -38
View File
@@ -21,11 +21,13 @@ DELETE /api/v1/accounts/:account_id/captain/assistants/:assistant_id
DELETE /api/v1/accounts/:account_id/captain/assistants/:assistant_id/documents/:document_id
DELETE /api/v1/accounts/:account_id/captain/assistants/:assistant_id/inboxes/:inbox_id
DELETE /api/v1/accounts/:account_id/captain/assistants/:assistant_id/scenarios/:scenario_id
DELETE /api/v1/accounts/:account_id/captain/assistants/:assistant_id/skills/:skill_id
DELETE /api/v1/accounts/:account_id/captain/auto_reply_rules/:rule_id
DELETE /api/v1/accounts/:account_id/captain/copilot_threads/:thread_id
DELETE /api/v1/accounts/:account_id/captain/custom_tools/:tool_id
DELETE /api/v1/accounts/:account_id/captain/documents/:document_id
DELETE /api/v1/accounts/:account_id/captain/scenarios/:scenario_id
DELETE /api/v1/accounts/:account_id/captain/skills/:skill_id
DELETE /api/v1/accounts/:account_id/channels/facebook_channel/:fb_id
DELETE /api/v1/accounts/:account_id/companies/:company_id
DELETE /api/v1/accounts/:account_id/companies/:company_id/avatar
@@ -38,6 +40,7 @@ DELETE /api/v1/accounts/:account_id/contacts/:contact_id/custom_attributes
DELETE /api/v1/accounts/:account_id/contacts/:contact_id/custom_attributes/:attribute_name
DELETE /api/v1/accounts/:account_id/contacts/:contact_id/notes/:note_id
DELETE /api/v1/accounts/:account_id/conversations/:conversation_id
DELETE /api/v1/accounts/:account_id/conversations/:conversation_id/ai_takeover
DELETE /api/v1/accounts/:account_id/conversations/:conversation_id/custom_attributes/:attribute_name
DELETE /api/v1/accounts/:account_id/conversations/:conversation_id/draft_messages
DELETE /api/v1/accounts/:account_id/conversations/:conversation_id/draft_messages/:draft_id
@@ -96,8 +99,6 @@ DELETE /api/v1/accounts/:account_id/portals/:portal_id/categories/:category_id
DELETE /api/v1/accounts/:account_id/portals/:portal_id/folders/:folder_id
DELETE /api/v1/accounts/:account_id/portals/:portal_id/logo
DELETE /api/v1/accounts/:account_id/portals/:portal_id/members/:member_id
DELETE /api/v1/accounts/:account_id/saml_settings
DELETE /api/v1/accounts/:account_id/saml_settings/:id
DELETE /api/v1/accounts/:account_id/sla_policies/:id
DELETE /api/v1/accounts/:account_id/sla_policies/:id/inboxes/:inbox_id
DELETE /api/v1/accounts/:account_id/tags/:tag_id
@@ -113,8 +114,6 @@ DELETE /api/v1/notification_subscriptions/:identifier
DELETE /api/v1/notifications/:id
DELETE /api/v1/notifications/destroy_all
DELETE /api/v1/profile/avatar
DELETE /api/v1/profile/mfa
DELETE /api/v1/profile/mfa/
DELETE /api/v1/profile/sessions/:id
DELETE /api/v1/push_subscriptions/:id
DELETE /api/v1/widget/labels/:label_id
@@ -128,6 +127,7 @@ DELETE /platform/api/v1/apps/:id/permissibles/:permissible_id
DELETE /platform/api/v1/banners/:id
DELETE /platform/api/v1/installation_configs/:id
DELETE /platform/api/v1/users/:id
GET /
GET /.well-known/apple-app-site-association
GET /.well-known/assetlinks.json
GET /.well-known/cf-custom-hostname-challenge/:id
@@ -178,6 +178,7 @@ GET /api/v1/accounts/:account_id/canned_responses
GET /api/v1/accounts/:account_id/canned_responses/
GET /api/v1/accounts/:account_id/canned_responses/:id
GET /api/v1/accounts/:account_id/canned_responses/search
GET /api/v1/accounts/:account_id/captain/assistant_responses
GET /api/v1/accounts/:account_id/captain/assistant_responses/
GET /api/v1/accounts/:account_id/captain/assistant_responses/:response_id
GET /api/v1/accounts/:account_id/captain/assistants
@@ -210,6 +211,8 @@ GET /api/v1/accounts/:account_id/captain/preferences
GET /api/v1/accounts/:account_id/captain/preferences/
GET /api/v1/accounts/:account_id/captain/scenarios/
GET /api/v1/accounts/:account_id/captain/scenarios/:scenario_id
GET /api/v1/accounts/:account_id/captain/skills
GET /api/v1/accounts/:account_id/captain/skills/:skill_id
GET /api/v1/accounts/:account_id/captain/tasks/follow_up
GET /api/v1/accounts/:account_id/captain/tasks/label_suggestion
GET /api/v1/accounts/:account_id/channels/facebook_channel/:fb_id
@@ -265,8 +268,10 @@ GET /api/v1/accounts/:account_id/csat_survey_responses
GET /api/v1/accounts/:account_id/csat_survey_responses/
GET /api/v1/accounts/:account_id/csat_survey_responses/download
GET /api/v1/accounts/:account_id/csat_survey_responses/metrics
GET /api/v1/accounts/:account_id/custom_attribute_definitions
GET /api/v1/accounts/:account_id/custom_attribute_definitions/
GET /api/v1/accounts/:account_id/custom_attribute_definitions/:id
GET /api/v1/accounts/:account_id/custom_filters
GET /api/v1/accounts/:account_id/custom_filters/
GET /api/v1/accounts/:account_id/custom_filters/:id
GET /api/v1/accounts/:account_id/custom_roles
@@ -387,8 +392,6 @@ GET /api/v1/accounts/:account_id/reports/labels
GET /api/v1/accounts/:account_id/reports/outgoing_messages_count
GET /api/v1/accounts/:account_id/reports/summary
GET /api/v1/accounts/:account_id/reports/teams
GET /api/v1/accounts/:account_id/saml_settings
GET /api/v1/accounts/:account_id/saml_settings/:id
GET /api/v1/accounts/:account_id/search
GET /api/v1/accounts/:account_id/search/articles
GET /api/v1/accounts/:account_id/search/contacts
@@ -423,9 +426,8 @@ GET /api/v1/accounts/:account_id/webhooks/:webhook_id
GET /api/v1/accounts/:account_id/whatsapp_calls/:id
GET /api/v1/accounts/all
GET /api/v1/auth/confirm_email
GET /api/v1/auth/mfa/status
GET /api/v1/auth/oauth/authorize
GET /api/v1/ldap/config
GET /api/v1/connector/shangwutong/inboxes
GET /api/v1/connector/shangwutong/inboxes/:inbox_id
GET /api/v1/notifications
GET /api/v1/notifications/unread_count
GET /api/v1/oidc/authorize
@@ -433,17 +435,13 @@ GET /api/v1/oidc/callback
GET /api/v1/oidc/config
GET /api/v1/oidc/discovery
GET /api/v1/profile
GET /api/v1/profile/mfa
GET /api/v1/profile/mfa/
GET /api/v1/profile/sessions
GET /api/v1/push_subscriptions
GET /api/v1/saml/login
GET /api/v1/saml/metadata
GET /api/v1/saml/slo
GET /api/v1/sso_sessions/:session_id
GET /api/v1/sso_sessions/user/:user_id
GET /api/v1/sso_sessions/user/:user_id/count
GET /api/v1/widget/campaigns
GET /api/v1/widget/config
GET /api/v1/widget/contact
GET /api/v1/widget/conversations
GET /api/v1/widget/conversations/toggle_status
@@ -493,7 +491,6 @@ GET /hc/:slug/:locale/categories/:category_slug/articles.json
GET /hc/:slug/:locale/search
GET /hc/:slug/articles/:article_slug
GET /hc/:slug/sitemap.xml
GET /health
GET /instagram/callback
GET /linear/callback
GET /microsoft/callback
@@ -526,10 +523,10 @@ GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id
GET /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/messages
GET /runtime-config.js
GET /shopify/callback
GET /tiktok/callback
GET /twitter/callback
GET /webhooks/fake/:identifier
GET /webhooks/instagram
GET /webhooks/tiktok/:business_id
GET /webhooks/twitter
@@ -601,6 +598,7 @@ PATCH /api/v1/accounts/:account_id/teams/:team_id
PATCH /api/v1/accounts/:account_id/teams/:team_id/team_members
PATCH /api/v1/accounts/:account_id/teams/:team_id/team_members/
PATCH /api/v1/accounts/:account_id/webhooks/:webhook_id
PATCH /api/v1/connector/shangwutong/inboxes/:inbox_id/contacts/:source_id
PATCH /api/v1/profile
PATCH /api/v1/widget/contact
PATCH /api/v1/widget/contact/set_user
@@ -653,6 +651,7 @@ POST /api/v1/accounts/:account_id/campaigns/:campaign_id/start
POST /api/v1/accounts/:account_id/campaigns/:campaign_id/stop
POST /api/v1/accounts/:account_id/canned_responses
POST /api/v1/accounts/:account_id/canned_responses/
POST /api/v1/accounts/:account_id/captain/assistant_responses
POST /api/v1/accounts/:account_id/captain/assistant_responses/
POST /api/v1/accounts/:account_id/captain/assistant_responses/process
POST /api/v1/accounts/:account_id/captain/assistants
@@ -661,6 +660,7 @@ POST /api/v1/accounts/:account_id/captain/assistants/:assistant_id/documents/
POST /api/v1/accounts/:account_id/captain/assistants/:assistant_id/inboxes
POST /api/v1/accounts/:account_id/captain/assistants/:assistant_id/playground
POST /api/v1/accounts/:account_id/captain/assistants/:assistant_id/scenarios/
POST /api/v1/accounts/:account_id/captain/assistants/:assistant_id/skills/:skill_id
POST /api/v1/accounts/:account_id/captain/auto_reply_rules
POST /api/v1/accounts/:account_id/captain/auto_reply_rules/
POST /api/v1/accounts/:account_id/captain/auto_reply_rules/evaluate
@@ -686,6 +686,7 @@ POST /api/v1/accounts/:account_id/captain/message_reports
POST /api/v1/accounts/:account_id/captain/rag/index/:response_id
POST /api/v1/accounts/:account_id/captain/rag/query
POST /api/v1/accounts/:account_id/captain/scenarios/
POST /api/v1/accounts/:account_id/captain/skills
POST /api/v1/accounts/:account_id/captain/tasks/follow_up
POST /api/v1/accounts/:account_id/captain/tasks/label_suggestion
POST /api/v1/accounts/:account_id/captain/tasks/reply_suggestion
@@ -720,6 +721,7 @@ POST /api/v1/accounts/:account_id/contacts/import
POST /api/v1/accounts/:account_id/contacts/merge
POST /api/v1/accounts/:account_id/conversations
POST /api/v1/accounts/:account_id/conversations/
POST /api/v1/accounts/:account_id/conversations/:conversation_id/ai_takeover
POST /api/v1/accounts/:account_id/conversations/:conversation_id/assign
POST /api/v1/accounts/:account_id/conversations/:conversation_id/assignments
POST /api/v1/accounts/:account_id/conversations/:conversation_id/custom_attributes
@@ -744,7 +746,9 @@ POST /api/v1/accounts/:account_id/conversations/:conversation_id/update_last_see
POST /api/v1/accounts/:account_id/conversations/:conversation_id/whatsapp_calls/
POST /api/v1/accounts/:account_id/conversations/filter
POST /api/v1/accounts/:account_id/csat_survey_responses/:id/update_review_notes
POST /api/v1/accounts/:account_id/custom_attribute_definitions
POST /api/v1/accounts/:account_id/custom_attribute_definitions/
POST /api/v1/accounts/:account_id/custom_filters
POST /api/v1/accounts/:account_id/custom_filters/
POST /api/v1/accounts/:account_id/custom_roles
POST /api/v1/accounts/:account_id/custom_roles/
@@ -829,9 +833,6 @@ POST /api/v1/accounts/:account_id/portals/:portal_id/categories/reorder
POST /api/v1/accounts/:account_id/portals/:portal_id/folders/
POST /api/v1/accounts/:account_id/portals/:portal_id/members/
POST /api/v1/accounts/:account_id/portals/:portal_id/send_instructions
POST /api/v1/accounts/:account_id/saml_settings
POST /api/v1/accounts/:account_id/saml_settings/
POST /api/v1/accounts/:account_id/saml_settings/:id/toggle_active
POST /api/v1/accounts/:account_id/sla_policies
POST /api/v1/accounts/:account_id/sla_policies/:id/inboxes
POST /api/v1/accounts/:account_id/tags/
@@ -856,32 +857,19 @@ POST /api/v1/accounts/:account_id/whatsapp_calls/:id/terminate
POST /api/v1/accounts/:account_id/whatsapp_calls/:id/upload_recording
POST /api/v1/accounts/:account_id/whatsapp_calls/initiate
POST /api/v1/auth/login
POST /api/v1/auth/login/mfa
POST /api/v1/auth/mfa/backup_codes
POST /api/v1/auth/mfa/disable
POST /api/v1/auth/mfa/enable
POST /api/v1/auth/mfa/verify
POST /api/v1/auth/oauth/callback
POST /api/v1/auth/refresh
POST /api/v1/auth/reset_password
POST /api/v1/auth/switch_account
POST /api/v1/ldap/login
POST /api/v1/ldap/test
POST /api/v1/auth/ws_ticket
POST /api/v1/notification_subscriptions
POST /api/v1/notifications/:id/snooze
POST /api/v1/notifications/:id/unread
POST /api/v1/notifications/read_all
POST /api/v1/profile/auto_offline
POST /api/v1/profile/availability
POST /api/v1/profile/mfa
POST /api/v1/profile/mfa/
POST /api/v1/profile/mfa/backup_codes
POST /api/v1/profile/mfa/verify
POST /api/v1/profile/resend_confirmation
POST /api/v1/profile/reset_access_token
POST /api/v1/push_subscriptions
POST /api/v1/saml/acs
POST /api/v1/saml/slo
POST /api/v1/sso_sessions/:session_id/terminate
POST /api/v1/sso_sessions/user/:user_id/terminate_all
POST /api/v1/widget/config
@@ -942,7 +930,6 @@ POST /twilio/voice/call/:phone
POST /twilio/voice/conference_status/:phone
POST /twilio/voice/recording_status/:phone
POST /twilio/voice/status/:phone
POST /webhooks/fake/:identifier
POST /webhooks/instagram
POST /webhooks/line/:line_channel_id
POST /webhooks/shopify
@@ -983,6 +970,7 @@ PUT /api/v1/accounts/:account_id/captain/custom_tools/:tool_id
PUT /api/v1/accounts/:account_id/captain/preferences
PUT /api/v1/accounts/:account_id/captain/preferences/
PUT /api/v1/accounts/:account_id/captain/scenarios/:scenario_id
PUT /api/v1/accounts/:account_id/captain/skills/:skill_id
PUT /api/v1/accounts/:account_id/companies/:company_id
PUT /api/v1/accounts/:account_id/contacts/:contact_id
PUT /api/v1/accounts/:account_id/contacts/:contact_id/notes/:note_id
@@ -1021,8 +1009,6 @@ PUT /api/v1/accounts/:account_id/portals/:portal_id/articles/:article_id
PUT /api/v1/accounts/:account_id/portals/:portal_id/categories/:category_id
PUT /api/v1/accounts/:account_id/portals/:portal_id/folders/:folder_id
PUT /api/v1/accounts/:account_id/portals/:portal_id/members/:member_id
PUT /api/v1/accounts/:account_id/saml_settings
PUT /api/v1/accounts/:account_id/saml_settings/:id
PUT /api/v1/accounts/:account_id/settings
PUT /api/v1/accounts/:account_id/sla_policies/:id
PUT /api/v1/accounts/:account_id/tags/:tag_id
@@ -1031,7 +1017,8 @@ PUT /api/v1/accounts/:account_id/web_widgets/offline_messages/:offline_message_i
PUT /api/v1/accounts/:account_id/web_widgets/offline_messages/:offline_message_id/dismiss
PUT /api/v1/accounts/:account_id/webhooks/:webhook_id
PUT /api/v1/auth/reset_password
PUT /api/v1/ldap/config
PUT /api/v1/connector/shangwutong/inboxes/:inbox_id/messages/:message_id/status
PUT /api/v1/connector/shangwutong/inboxes/:inbox_id/status
PUT /api/v1/notifications/:id
PUT /api/v1/oidc/config
PUT /api/v1/profile
@@ -1051,4 +1038,4 @@ PUT /public/api/v1/csat_survey/:id
PUT /public/api/v1/inboxes/:inbox_id/contacts/:contact_id
PUT /public/api/v1/inboxes/:inbox_id/contacts/:contact_id/conversations/:conversation_id/messages/:message_id
PUT /widget/direct_uploads/:upload_uuid
TOTAL: 1053
TOTAL: 1040
+9 -9
View File
@@ -2,18 +2,22 @@
Generated from:
- GoChat route dump: `docs/parity/gochat-routes.txt`
- Chatwoot route source: `docs/chatwoot/config/routes.rb`
- GoChat route dump: `../docs/parity/gochat-routes.txt`
- Chatwoot route source: `../docs/chatwoot/config/routes.rb`
This report covers tracked frontend-critical Chatwoot 4.15.1 routes from `docs/chatwoot/config/routes.rb`, including API v1 account routes, Captain/Copilot, assignment policies, widget/public APIs, and API v2 reports. Ruby is not installed in the workspace, so Chatwoot routes are sourced from static route declarations instead of `bin/rails routes`.
Summary: 447 exact, 0 method-compatible, 9 parameter-compatible, 0 missing out of 456 tracked critical routes.
Summary: 443 exact, 0 method-compatible, 9 parameter-compatible, 5 missing out of 457 tracked critical routes.
## Missing Critical Routes
| Method | Chatwoot Path | GoChat Match | Controller | Source | Status |
| --- | --- | --- | --- | --- | --- |
| - | - | - | - | - | none |
| DELETE | `/api/v1/profile/mfa` | `-` | `api/v1/profile/mfa#destroy` | `routes.rb:433` | missing |
| GET | `/api/v1/profile/mfa` | `-` | `api/v1/profile/mfa#show` | `routes.rb:433` | missing |
| POST | `/api/v1/profile/mfa` | `-` | `api/v1/profile/mfa#create` | `routes.rb:433` | missing |
| POST | `/api/v1/profile/mfa/backup_codes` | `-` | `api/v1/profile/mfa#backup_codes` | `routes.rb:435` | missing |
| POST | `/api/v1/profile/mfa/verify` | `-` | `api/v1/profile/mfa#verify` | `routes.rb:434` | missing |
## Method-Compatible Routes
@@ -92,9 +96,9 @@ These routes exist with equivalent method and path shape but different parameter
| DELETE | `/api/v1/accounts/:account_id/webhooks/:webhook_id` | `/api/v1/accounts/:account_id/webhooks/:webhook_id` | `api/v1/accounts/webhooks#destroy` | `routes.rb:342` | exact |
| DELETE | `/api/v1/notification_subscriptions` | `/api/v1/notification_subscriptions` | `api/v1/notification_subscriptions#destroy` | `routes.rb:440` | exact |
| DELETE | `/api/v1/profile/avatar` | `/api/v1/profile/avatar` | `api/v1/profiles#avatar` | `routes.rb:422` | exact |
| DELETE | `/api/v1/profile/mfa` | `/api/v1/profile/mfa` | `api/v1/profile/mfa#destroy` | `routes.rb:433` | exact |
| DELETE | `/api/v1/profile/sessions/:id` | `/api/v1/profile/sessions/:id` | `api/v1/profile/sessions#destroy` | `routes.rb:445` | exact |
| DELETE | `/api/v1/widget/labels/:label_id` | `/api/v1/widget/labels/:label_id` | `api/v1/widget/labels#destroy` | `routes.rb:464` | exact |
| GET | `/` | `/` | `dashboard#index` | `routes.rb:17` | exact |
| GET | `/.well-known/apple-app-site-association` | `/.well-known/apple-app-site-association` | `apple_app#site_association` | `routes.rb:658` | exact |
| GET | `/.well-known/assetlinks.json` | `/.well-known/assetlinks.json` | `android_app#assetlinks` | `routes.rb:657` | exact |
| GET | `/.well-known/cf-custom-hostname-challenge/:id` | `/.well-known/cf-custom-hostname-challenge/:id` | `custom_domains#verify` | `routes.rb:660` | exact |
@@ -218,7 +222,6 @@ These routes exist with equivalent method and path shape but different parameter
| GET | `/api/v1/accounts/:account_id/webhooks` | `/api/v1/accounts/:account_id/webhooks` | `api/v1/accounts/webhooks#index` | `routes.rb:342` | exact |
| GET | `/api/v1/accounts/:account_id/whatsapp_calls/:id` | `/api/v1/accounts/:account_id/whatsapp_calls/:id` | `api/v1/accounts/whatsapp_calls#show` | `routes.rb:237` | exact |
| GET | `/api/v1/profile` | `/api/v1/profile` | `api/v1/profiles#show` | `routes.rb:421` | exact |
| GET | `/api/v1/profile/mfa` | `/api/v1/profile/mfa` | `api/v1/profile/mfa#show` | `routes.rb:433` | exact |
| GET | `/api/v1/profile/sessions` | `/api/v1/profile/sessions` | `api/v1/profile/sessions#index` | `routes.rb:445` | exact |
| GET | `/api/v1/widget/campaigns` | `/api/v1/widget/campaigns` | `api/v1/widget/campaigns#index` | `routes.rb:445` | exact |
| GET | `/api/v1/widget/contact` | `/api/v1/widget/contact` | `api/v1/widget/contact#show` | `routes.rb:458` | exact |
@@ -413,9 +416,6 @@ These routes exist with equivalent method and path shape but different parameter
| POST | `/api/v1/notification_subscriptions` | `/api/v1/notification_subscriptions` | `api/v1/notification_subscriptions#create` | `routes.rb:440` | exact |
| POST | `/api/v1/profile/auto_offline` | `/api/v1/profile/auto_offline` | `api/v1/profiles#auto_offline` | `routes.rb:425` | exact |
| POST | `/api/v1/profile/availability` | `/api/v1/profile/availability` | `api/v1/profiles#availability` | `routes.rb:424` | exact |
| POST | `/api/v1/profile/mfa` | `/api/v1/profile/mfa` | `api/v1/profile/mfa#create` | `routes.rb:433` | exact |
| POST | `/api/v1/profile/mfa/backup_codes` | `/api/v1/profile/mfa/backup_codes` | `api/v1/profile/mfa#backup_codes` | `routes.rb:435` | exact |
| POST | `/api/v1/profile/mfa/verify` | `/api/v1/profile/mfa/verify` | `api/v1/profile/mfa#verify` | `routes.rb:434` | exact |
| POST | `/api/v1/profile/resend_confirmation` | `/api/v1/profile/resend_confirmation` | `api/v1/profiles#resend_confirmation` | `routes.rb:427` | exact |
| POST | `/api/v1/profile/reset_access_token` | `/api/v1/profile/reset_access_token` | `api/v1/profiles#reset_access_token` | `routes.rb:428` | exact |
| POST | `/api/v1/widget/config` | `/api/v1/widget/config` | `api/v1/widget/config#create` | `routes.rb:444` | exact |