feat: Alarms System - Database, API & Dashboard UI (#267)#349
feat: Alarms System - Database, API & Dashboard UI (#267)#349mendarb wants to merge 2 commits intodatabuddy-analytics:mainfrom
Conversation
|
@mendarb is attempting to deploy a commit to the Databuddy OSS Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR implements the full alarms system (database schema, API router, and dashboard UI), replacing the "Coming Soon" notifications page with a functional alarm management interface. The database layer and test coverage are solid, but the API router has a security gap and a couple of code-quality issues that should be addressed before merging. Key findings:
Confidence Score: 2/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as Dashboard UI
participant RPC as alarmsRouter
participant Auth as checkOrgPermission
participant DB as Database
UI->>RPC: alarms.create(payload)
RPC->>Auth: verify "update" permission
RPC->>DB: INSERT alarms
DB-->>UI: Alarm
UI->>RPC: alarms.list()
RPC->>Auth: verify membership
RPC->>DB: SELECT alarms
DB-->>UI: Alarm[]
UI->>RPC: alarms.update(id, fields)
RPC->>DB: findFirst alarm
RPC->>Auth: verify "read" then "update"
RPC->>DB: UPDATE alarms
DB-->>UI: Alarm
UI->>RPC: alarms.test(id)
RPC->>DB: findFirst alarm
RPC->>Auth: verify "read" permission
RPC->>RPC: send to each channel
RPC-->>UI: results
UI->>RPC: alarms.delete(id)
RPC->>DB: findFirst alarm
RPC->>Auth: verify "read" then "update"
RPC->>DB: DELETE alarm
DB-->>UI: success
|
| } | ||
|
|
||
| interface AlarmDialogProps { | ||
| alarm: Alarm | null; |
There was a problem hiding this comment.
unknown type violates project guidelines
The project guideline (01-MUST-DO.mdc) states: "do NOT use types any, unknown or never, use proper explicit types". Record<string, unknown> appears in this file (triggerConditions) and the same Alarm interface in page.tsx. Both should use an explicit type or, at minimum, a named opaque type.
The same violation exists at page.tsx line 407 (webhookHeaders: Record<string, string> | null) and line 408 (triggerConditions: Record<string, unknown> | null), and in alarms.ts at the updateData object (Record<string, unknown>).
Context Used: Basic guidelines for the project so vibe coders do... (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
|
|
||
| type TriggerType = (typeof TRIGGER_TYPES)[number]["value"]; | ||
| type Channel = (typeof CHANNELS)[number]["value"]; | ||
|
|
||
| export function AlarmDialog({ alarm, isOpen, onCloseAction }: AlarmDialogProps) { | ||
| const queryClient = useQueryClient(); |
There was a problem hiding this comment.
Email channel selectable but non-functional
The dialog lets users pick "email" as a notification channel, which will be persisted to the database. However, the test endpoint in alarms.ts always returns { channel: "email", success: false, error: "Email notifications are not yet configured" }, and the right sidebar shows "Email (coming soon)".
This creates a confusing experience: users can create and save an alarm with the email channel, but it will silently never deliver, and the test will report a failure. Consider either:
- Disabling the email option in the UI until the feature is ready, or
- Adding a tooltip/badge clearly marking it as unavailable.
|
@greptile-apps Thanks for the review! All issues have been addressed in the latest push:
|
|
Perfect! I've verified all the fixes: ✅ BOLA fix — All security and UX issues resolved. LGTM! 🚀 |
…board UI Implements the complete alarms system (databuddy-analytics#267): - Database: alarms table with trigger types, notification channels, and proper indexes - API: CRUD endpoints (list, get, create, update, delete, test) via ORPC - Dashboard: notifications settings page with alarm management UI - Tests: validation schema tests for create/update operations - Integrates with @databuddy/notifications package for Slack, Discord, and webhook delivery Closes databuddy-analytics#267 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix BOLA vulnerability: authorize user ownership when alarm.organizationId is null - Fix broken delete UX: add try/catch and onError handler for delete mutation - Remove unused `and` import, replace with `inArray` (was dynamically imported) - Move `inArray` import to top-level static import - Replace `Record<string, unknown>` with properly typed interface for updateData Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
eddd453 to
3afd8bc
Compare
Summary
Complete implementation of the alarms system as described in #267:
alarmstable topackages/db/src/drizzle/schema.tswith all required fields (name, description, enabled, notification channels, webhook URLs, email addresses, trigger type/conditions). Indexes onuser_id,organization_id,website_id, andenabled. Relations defined inrelations.ts.packages/rpc/src/routers/alarms.tswith full CRUD operations (alarms.list,alarms.get,alarms.create,alarms.update,alarms.delete,alarms.test). All endpoints use Zod validation, proper authorization viacheckOrgPermission, and the@databuddy/notificationspackage for test notifications.apps/dashboard/app/(main)/settings/notifications/page.tsxwith a functional alarm management page. Includes alarm list with enable/disable toggles, test notification button, create/edit dialog with channel configuration, and delete confirmation.packages/rpc/src/routers/alarms.test.tscovering create/update validation, invalid inputs, and edge cases.Technical Choices
Option A(simple text fields) for notification channels rather than a separate table, matching existing patterns in the codebasecheckOrgPermissionandrequireUserIdhelpers for authorizationrounded(notrounded-xl/rounded-md)AI Disclosure
This PR was created with AI assistance (Claude Code). All code has been reviewed and verified.
Closes #267