Skip to content

Commit bfd6a2d

Browse files
pktikkaniclaude
andcommitted
feat: Complete Access Review API with all features
Added: - updateCampaign and completeCampaign endpoints - Designated Owners CRUD (list, get, create, update, delete, getOwnersForSite) - Notifications system (list, create, markRead, markAllRead, delete) - Review item details (getItem) - Bulk operations (bulkRetainAll) - Campaign reports (getCampaignReport) - Schedule runner (runSchedule) - Auto-scheduler job for scheduled reviews Features: - Auto-create campaigns from schedules at next run time - Auto-send reminder notifications (7, 3, 1 days before due) - Auto-retain pending items for autoExecute schedules - Overdue campaign notifications Updated Prisma schema: - DesignatedOwner model with userId, siteUrl, ownerType, notes, isActive - AccessReviewNotification model with userId, title, message, readAt - AccessReviewCampaign with scheduledReviewId field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 065ca9d commit bfd6a2d

5 files changed

Lines changed: 941 additions & 14 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ on:
55
branches:
66
- main
77
- railway-version
8+
- access-review
89
pull_request:
910
branches:
1011
- main
12+
- access-review
1113

1214
env:
1315
NODE_VERSION: '20.x'

prisma/schema.prisma

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ model AccessReviewCampaign {
123123
createdById String
124124
createdBy User @relation(fields: [createdById], references: [id])
125125
126+
// If created from a schedule
127+
scheduledReviewId String?
128+
126129
items AccessReviewItem[]
127130
notifications AccessReviewNotification[]
128131
@@ -133,6 +136,7 @@ model AccessReviewCampaign {
133136
@@index([status])
134137
@@index([createdById])
135138
@@index([dueDate])
139+
@@index([scheduledReviewId])
136140
@@map("access_review_campaigns")
137141
}
138142

@@ -208,46 +212,59 @@ model AccessReviewDecision {
208212
model DesignatedOwner {
209213
id String @id @default(cuid())
210214
215+
// Who created this
216+
userId String
217+
211218
// Resource matching
212-
resourceType String // site, drive, folder, path_pattern
213-
resourcePattern String @db.Text // URL or pattern
219+
siteUrl String @db.Text // Site URL this owner is designated for
214220
215221
// Owner info
216222
ownerEmail String
217223
ownerName String?
224+
ownerType String @default("primary") // primary, backup, delegate
225+
226+
// Notes and status
227+
notes String? @db.Text
228+
isActive Boolean @default(true)
218229
219230
// Options
220-
isPrimarySiteOwner Boolean @default(false) // Use SharePoint site owner
221-
notifyOnReview Boolean @default(true)
231+
notifyOnReview Boolean @default(true)
222232
223233
createdAt DateTime @default(now())
224234
updatedAt DateTime @updatedAt
225235
226-
@@unique([resourceType, resourcePattern])
236+
@@unique([userId, siteUrl, ownerEmail])
237+
@@index([userId])
238+
@@index([siteUrl])
227239
@@index([ownerEmail])
240+
@@index([isActive])
228241
@@map("designated_owners")
229242
}
230243

231244
model AccessReviewNotification {
232-
id String @id @default(cuid())
233-
campaignId String
234-
campaign AccessReviewCampaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
245+
id String @id @default(cuid())
246+
userId String
247+
248+
// Optional campaign link
249+
campaignId String?
250+
campaign AccessReviewCampaign? @relation(fields: [campaignId], references: [id], onDelete: Cascade)
235251
236252
// Notification details
237-
type String // campaign_started, reminder, completed, action_required
238-
recipient String
239-
subject String
240-
body String @db.Text
253+
type String // campaign_started, campaign_due_soon, campaign_overdue, review_assigned, execution_complete, schedule_triggered
254+
title String
255+
message String @db.Text
241256
242257
// Status
243-
sentAt DateTime?
258+
readAt DateTime?
259+
sentAt DateTime? // For email notifications
244260
error String?
245261
246262
createdAt DateTime @default(now())
247263
264+
@@index([userId])
248265
@@index([campaignId])
249266
@@index([type])
250-
@@index([sentAt])
267+
@@index([readAt])
251268
@@map("access_review_notifications")
252269
}
253270

0 commit comments

Comments
 (0)