6 · Optional integrations
Objective — surface (don’t silently skip) the optional integrations — Slack notifications for errors/deploys/backups, GitHub project management (labels, issue forms, project board, PR template), and privacy-first Rybbit analytics — so operations and feedback loops are wired before users arrive.
Background
Section titled “Background”These are OPTIONAL but valuable. Per the phase’s optional-tasks policy, surface each one and let the operator decide — never silently skip. Configure them now if you have the time; defer explicitly if not.
flowchart LR Sentry["Sentry errors"] --> Alerts["#app-alerts"] Deployer["Deployer"] --> Deploys["#app-deploys"] Backup["Backups"] --> Backups["#app-backups"] Alerts --> Slack(["Slack workspace"]) Deploys --> Slack Backups --> Slack1. Wire Slack notifications (OPTIONAL)
Section titled “1. Wire Slack notifications (OPTIONAL)”Automated Slack alerts for Sentry errors, deployments, and backup status.
-
Set up the workspace (first project only). If you don’t have a workspace, create one at slack.com/create. Create an incoming-webhook app: api.slack.com/apps → Create New App → From scratch → name
<Org> Notifications→ Incoming Webhooks → Activate ON → Add New Webhook to Workspace → pick a channel → copy the URL (https://hooks.slack.com/services/T…/B…/xxx). Store the webhook URL, workspace, app name, and creation date in your password manager.- ✅ The workspace + incoming-webhook app exist, URL stored in the vault.
-
Create the project channels & webhooks — one channel per concern, then a channel-specific webhook for each.
Channel Purpose #<app>-alertsSentry errors and critical alerts #<app>-deploysDeployment notifications #<app>-backupsBackup success/failure (optional) Add the webhook URLs to
.env(real values) and.env.example(placeholders, safe to commit):Terminal window ## === SLACK NOTIFICATIONS ===SLACK_ALERTS_WEBHOOK=<your-slack-alerts-webhook-url>SLACK_DEPLOYS_WEBHOOK=<your-slack-deploys-webhook-url>SLACK_BACKUPS_WEBHOOK=<your-slack-backups-webhook-url># Expected: placeholders in .env.example; real webhook URLs in .env- ✅ Per-concern channels exist with webhook URLs wired into env.
-
Wire the integrations.
-
Sentry → Slack (requires Sentry Team plan) — Settings → Integrations → Slack → authorize, then Alerts → Create Alert Rule (
> 0 errors in 1 min, filterproduction, action: send to#<app>-alerts). On the free plan, skip and track via a GitHub issue. -
Deployer → Slack — add success/failure tasks to
deploy.php:use Deployer\Utility\Httpie;task('slack:notify:success', function () {$webhookUrl = getenv('SLACK_DEPLOYS_WEBHOOK');if (!$webhookUrl) { writeln('<comment>SLACK_DEPLOYS_WEBHOOK not set - skipping</comment>'); return; }$app = get('application', 'App');$stage = get('labels')['stage'] ?? 'unknown';$branch = run('git rev-parse --abbrev-ref HEAD', ['timeout' => 5])->toString();$commit = run('git log -1 --oneline', ['timeout' => 5])->toString();Httpie::post($webhookUrl)->body(['text' => "*{$app}* deployed to *{$stage}*\nBranch: `{$branch}`\nCommit: {$commit}",'username' => 'Deployer', 'icon_emoji' => ':rocket:',])->send();})->desc('Send deploy success notification to Slack');task('slack:notify:failure', function () {$webhookUrl = getenv('SLACK_DEPLOYS_WEBHOOK');if (!$webhookUrl) { return; }$app = get('application', 'App');$stage = get('labels')['stage'] ?? 'unknown';Httpie::post($webhookUrl)->body(['text' => "*{$app}* deployment to *{$stage}* failed\nCheck logs for details.",'username' => 'Deployer', 'icon_emoji' => ':x:',])->send();})->desc('Send deploy failure notification to Slack');after('deploy:success', 'slack:notify:success');after('deploy:failed', 'slack:notify:failure'); -
Backups → Slack — easiest is to rely on Sentry Cron Monitors (no extra config). Otherwise add a
slackblock toconfig/backup.php’snotificationswith'webhook_url' => env('SLACK_BACKUPS_WEBHOOK'). -
✅ The Sentry, Deployer, and backup notification paths are wired (or consciously skipped).
-
-
Test the webhook.
Terminal window set -a && source .env && set +a # or export each SLACK_*_WEBHOOK you testcurl -X POST -H 'Content-type: application/json' \--data '{"text":"Slack webhook test successful!"}' \"$SLACK_ALERTS_WEBHOOK"# Expected: "ok" and the message appears in the channelThen run
dep deploy stagingand confirm the notification lands in#<app>-deploys. Finally, add theSLACK_*_WEBHOOKvars to the production.envand clear the config cache.- ✅ The test
curlreturnsokand a real deploy notifies#<app>-deploys.
- ✅ The test
2. Set up project management (OPTIONAL)
Section titled “2. Set up project management (OPTIONAL)”Set up GitHub Issues, typed labels, YAML issue forms, a project board, and a PR template.
-
Create the typed labels. At
github.com/<org>/<repo>/labels: delete the redundant defaults (bug,documentation,enhancement,question— replaced by typed labels), keepduplicate/good first issue/help wanted/invalid/wontfix, then create four typed families (~25 labels total).Family Labels (color) Priority priority: critical#b60205,high#d93f0b,medium#fbca04,low#0e8a16Type type: bug#d73a4a,feature#a2eeef,enhancement#7057ff,docs#0075ca,refactor#f9d0c4,security#ee0701,question#d876e3Status status: triage#cfd3d7,confirmed#1d76db,in-progress#5319e7,blocked#e99695,needs-info#d876e3Area area: frontend#bfd4f2,backend#b4a7d6,database#c5def5,devops#d4c5f9(+ optionalauth/payments/api)- ✅ The four typed label families exist.
-
Create the issue forms under
.github/ISSUE_TEMPLATE/. Examplebug_report.yml:name: Bug Reportdescription: Report a bug or unexpected behaviortitle: "[BUG] "labels: ["type: bug", "status: triage"]body:- type: textareaid: descriptionattributes: { label: Bug Description }validations: { required: true }- type: textareaid: stepsattributes: { label: Steps to Reproduce }validations: { required: true }- type: textareaid: expectedattributes: { label: Expected Behavior }validations: { required: true }- type: dropdownid: severityattributes:label: Severityoptions:- Critical (app unusable, data loss)- High (major feature broken)- Medium (workaround exists)- Low (minor inconvenience)validations: { required: true }- type: checkboxesid: checklistattributes:label: Pre-submission Checklistoptions:- label: I searched existing issues to ensure this is not a duplicaterequired: trueAdd
feature_request.yml(problem statement, proposed solution, importance dropdown) andtask.yml(description, acceptance criteria, area dropdown) on the same pattern, plusconfig.ymlto disable blank issues and route security reports privately:blank_issues_enabled: falsecontact_links:- name: Documentationurl: https://docs.<domain>about: Check the docs before opening an issue- name: Security Vulnerabilityurl: https://github.com/<org>/<repo>/security/advisories/newabout: Report security vulnerabilities privately- ✅ Bug/feature/task issue forms +
config.ymlexist under.github/ISSUE_TEMPLATE/.
- ✅ Bug/feature/task issue forms +
-
Create the project board. Organization → Projects → New project → Kanban → name
<App> Development; Status field: Backlog, Triage, Todo, In Progress, In Review, Done; custom fieldsPriority(Critical/High/Medium/Low), optionalEstimate(XS–XL); workflows item added → Backlog, reopened → Todo, closed / PR merged → Done, Enable Auto-add with filteris:issue is:open; link it:gh project link <number> --owner <owner> --repo <owner>/<repo>.- ✅ The Kanban board exists, is linked, and auto-adds open issues.
-
Create the PR template & discussions. Create
.github/PULL_REQUEST_TEMPLATE.mdwith sections: Description, Type of Change, Related Issues, Changes Made, Screenshots, Testing Instructions, Checklist, Deployment Notes. Optionally enable Discussions (Settings → General → Features). Commit.github/once done.- ✅ The PR template is committed and Discussions are enabled if wanted.
3. Set up Rybbit analytics (OPTIONAL)
Section titled “3. Set up Rybbit analytics (OPTIONAL)”Privacy-first, cookieless analytics — session replay, funnels, goals, web vitals, and error tracking with no consent banner. A complement to (not replacement for) Google Analytics.
-
Activate & add the site. app.rybbit.io/redeem → redeem license → Dashboard → Sites → Add Website (domain, no
https://) → set Public Analytics Off, User ID Salting On → copy the Site ID.- ✅ The site is added and its Site ID is copied.
-
Configure the site settings — Block Bot Traffic On, Track IP Address Off, Web Vitals On, Error Tracking On, Track Outbound Links On, Track SPA Navigation On; connect Google Search Console.
- ✅ The site settings match the privacy-first profile.
-
Install the tracking script — find layout files with a
<head>and add the tracking script (ideally a sharedpartials/analytics.blade.php).Terminal window grep -r "<!DOCTYPE html" resources/views/ packages/ --include="*.blade.php" -l# Expected: the layout files with a <head> to inject the script.env RYBBIT_SITE_ID=<your-site-id>config/services.php 'rybbit' => ['site_id' => env('RYBBIT_SITE_ID')],- ✅ The tracking script is wired via a shared partial and the Site ID is in env/config.
-
Set skip & mask patterns — Dashboard → Settings → Tracking Script: skip
/admin/**,/setting/**; mask/users/*/profile.- ✅ Admin paths are skipped and sensitive paths masked.
-
Enable the dashboard features — Performance (Web Vitals); Session Replay On with Masking + Mask All Inputs On; Error Tracking On.
- ✅ Performance, masked session replay, and error tracking are on.
-
Wire custom events & identity.
<button data-rybbit-event="signup_clicked">Sign Up</button>window.rybbit.event("plan_purchased", { plan: "pro", interval: "yearly" });// inside an @auth block:window.rybbit.identify("{{ auth()->id() }}");- ✅ Custom events and authenticated-user identity are wired.
-
Create goals & funnels — goals (Signup Completed, Pricing Page Viewed, Trial Started) and a funnel (
/→/pricing→/register→ event).- ✅ Goals and a conversion funnel exist.
-
Deploy & verify. Deploy, set
RYBBIT_SITE_IDin production,php artisan config:clear && php artisan view:clear, then visit the site in incognito and confirm hits in the Rybbit real-time dashboard. Store the Site ID, account email, dashboard URL, tier, and any API key in your password manager.- ✅ Real-time hits appear in the Rybbit dashboard after deploy.
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 🔀 Slack webhook test posts — Deployer notifies
#<app>-deploys(or consciously deferred). - 🔀 GitHub labels, issue forms, project board, PR template — in place (or deferred).
- 🔀 Rybbit live and recording hits — admin paths skipped and inputs masked (or deferred).
- 👤 Every deferred item was surfaced — to the operator, not silently skipped.