Harden Hafa Code for the FDMS classroom launch#8
Conversation
✅ Deploy Preview for hafa-code ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus 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 |
Summary
Verification
Deployment and school gates
Application code is ready for review. Before student launch, deploy both services and verify Netlify/Render/Clerk production settings, configure Resend and Solid Queue operation, complete FDMS privacy and sharing approval, verify backup restore and monitoring, and run the documented 2–4 student pilot.
Greptile Summary
This PR hardens Hafa Code for a classroom launch across the full stack: teacher/student feedback threads, durable optimistic-lock cloud saves with conflict-copy recovery, bulk invitations with delivery tracking, classroom archive/export/audit workflows, and quota + share-throttle hardening. The changes are well-tested (50 Rails tests, 10 React tests) and internally consistent.
ProjectComment/ProjectCommentReadmodels with aproject_commentscontroller;file_path_belongs_to_projectis scoped towill_save_change_to_file_path?so resolve operations are never blocked by stale file references.localStorage, exponential retry with three attempts, and a conflict-copy branch that preserves local edits when optimistic locking detects a stale write.archived_at/school_yearon organisations; archive gate applied consistently across projects, checkpoints, invitations, and member management; bulk invite with domain allow-list and 100-address cap.Confidence Score: 5/5
Safe to merge — no correctness defects in the changed paths; all three inline findings are non-blocking quality notes.
The changes are thoroughly tested and the core flows (conflict resolution, archive gating, feedback auth) are correct. The three findings are style/performance notes: a double membership lookup per comment author largely mitigated by Rails' request-level query cache, a rate-limit off-by-one permitting 61 rather than 60 requests per window, and misleading error messaging when archived-classroom saves retry. None affects data integrity or security.
Files Needing Attention: api/app/controllers/api/v1/project_comments_controller.rb (membership N+1 in comment_author_role) and web/src/App.tsx (cloud-sync retry on archived workspace) are the two spots worth a follow-up before the classroom grows large.
Important Files Changed
Sequence Diagram
sequenceDiagram participant FE as Frontend (React) participant SS as cloudSyncStorage (localStorage) participant API as Rails API participant DB as Database Note over FE,DB: Cloud save with optimistic locking FE->>SS: markProjectPendingCloudSync(id, updatedAt) FE->>API: "PATCH /projects/:id {lock_version}" alt lock_version matches DB API->>DB: "UPDATE projects SET lock_version = lock_version + 1" API-->>FE: "200 {project, lock_version: N+1}" FE->>SS: clearProjectPendingCloudSync(id) else lock_version mismatch (StaleObjectError) API-->>FE: "409 {code: project_conflict, project: serverVersion}" FE->>FE: createConflictCopy(localProject) FE->>SS: markProjectPendingCloudSync(conflictCopy.id) FE->>API: "POST /projects {conflictCopy}" API-->>FE: "201 {project: savedConflictCopy}" end Note over FE,DB: Teacher feedback thread FE->>API: GET /projects/:id/comments API->>DB: SELECT project_comments + users + resolved_by API-->>FE: "{comments, unread_count}" FE->>API: POST /projects/:id/comments/mark_read API->>DB: "UPSERT project_comment_reads SET read_at = now" Note over FE,DB: Classroom archive FE->>API: PATCH /organizations/:id/archive API->>DB: "UPDATE organizations SET archived_at = now" API->>DB: INSERT audit_events API-->>FE: "{organization: {archived_at: ...}}" FE->>FE: "workspaceArchived = true, canEditProject = false"Reviews (4): Last reviewed commit: "Address Greptile classroom edge cases" | Re-trigger Greptile