Backend:
- Create hermes Django app with models: ReadingGroup, GroupBook, Section, ReadingSchedule, MemberProgress
- EPUB section splitting service with automatic detection and reading time estimation
- Section recommendation engine for 4-week meeting schedule
- REST API endpoints for groups, books, sections, schedule, and member progress
- Manual section adjustment (merge/split) support
Frontend:
- GroupsPage: list/create reading groups
- GroupDetailPage: manage members, upload EPUB to group, view group books
- GroupBookPage: section breakdown with merge/split controls, reading schedule, member progress
- API client and TypeScript types for all group operations
- i18n keys for English and Spanish
Shared:
- Group-related types and API endpoint constants in packages/shared
These MUST be resolved before this PR can be merged.
[File: backend/apps/groups/views.py | Line ~942]missing type hints
The IsGroupAdmin.has_permission and IsGroupAdmin.has_object_permission methods use object as the type hint for the view parameter. This should be typed properly per the project's Python 3.10+ type hints standard.
[File: backend/apps/groups/views.py | Line ~1218]missing permission flexibility for progress endpoint
The GroupBookViewSet has permission_classes = [permissions.IsAuthenticated, IsGroupAdmin] which means only group admins can access the progress endpoint. However, according to AC #6, "when I have confirmed the section recommendations, then all group members should be able to see the reading schedule with target sections per meeting." Members should be able to view and update their own progress, but the current permission class blocks them.
[File: frontend/src/pages/GroupBookPage.tsx | Throughout]inline styles
Multiple React components use inline styles extensively. Per project standards, inline styles are not allowed. Must use CSS modules, styled-components, or a consistent styling solution.
[File: frontend/src/pages/GroupDetailPage.tsx | Throughout]inline styles
Same inline styles issue as above. All React components have extensive inline styling.
[File: frontend/src/pages/GroupsPage.tsx | Throughout]inline styles
Same inline styles issue. The entire component uses inline styles.
[File: backend/apps/groups/views.py | Lines ~1115-1191]business logic in views
The adjust_sections action contains significant business logic for merging and splitting sections. Per Django review criteria, business logic should live in the service layer (section_splitting.py) rather than in views.
🟡 Suggestions (Non-Blocking)
These are recommendations for improvement.
[File: backend/apps/groups/services/section_splitting.py] Add docstrings to the _fetch_chapter_text and _estimate_reading_minutes helper functions.
[File: frontend/src/api/groups.ts | Line ~1318] The listGroups API returns either a paginated response or an array; consider adding explicit type guard handling.
[File: backend/apps/groups/models.py | Line ~337] Consider adding a db_index to estimated_reading_minutes field.
[File: backend/apps/groups/views.py | Line ~1242] The _renumber_sections function makes N individual queries for each section. Consider using bulk_update for efficiency.
Given I am a group admin, When I navigate to the group book section, Then I should see an option to upload an EPUB file.
Given I have selected an EPUB file to upload, When I confirm the upload, Then the system should parse the EPUB and identify chapter/section boundaries.
Given the EPUB has been parsed, When I view the section breakdown, Then I should see a list of detected sections with titles and estimated reading time for each.
Given I am viewing the section breakdown, When I choose to adjust section boundaries, Then I should be able to merge or split sections manually.
Given the EPUB has been split into sections, When I request section recommendations for meetings, Then the system should suggest which sections to assign to each weekly meeting.
Given I have confirmed the section recommendations, When I finalize the group book schedule, Then all group members should be able to see the reading schedule. (BLOCKING: Permission issue)
Given I am a group admin, When I want to replace the current book, Then I should be able to upload a new EPUB and restart the section splitting process without losing group membership.
## Reid's Review — PR #35
**Verdict:** 🔴 Changes Required
---
### 🔴 Blocking Issues
> These MUST be resolved before this PR can be merged.
- **[File: backend/apps/groups/views.py | Line ~942]** `missing type hints`
The `IsGroupAdmin.has_permission` and `IsGroupAdmin.has_object_permission` methods use `object` as the type hint for the `view` parameter. This should be typed properly per the project's Python 3.10+ type hints standard.
- **[File: backend/apps/groups/views.py | Line ~1218]** `missing permission flexibility for progress endpoint`
The `GroupBookViewSet` has `permission_classes = [permissions.IsAuthenticated, IsGroupAdmin]` which means only group admins can access the progress endpoint. However, according to AC #6, "when I have confirmed the section recommendations, then all group members should be able to see the reading schedule with target sections per meeting." Members should be able to view and update their own progress, but the current permission class blocks them.
- **[File: frontend/src/pages/GroupBookPage.tsx | Throughout]** `inline styles`
Multiple React components use inline styles extensively. Per project standards, inline styles are not allowed. Must use CSS modules, styled-components, or a consistent styling solution.
- **[File: frontend/src/pages/GroupDetailPage.tsx | Throughout]** `inline styles`
Same inline styles issue as above. All React components have extensive inline styling.
- **[File: frontend/src/pages/GroupsPage.tsx | Throughout]** `inline styles`
Same inline styles issue. The entire component uses inline styles.
- **[File: backend/apps/groups/views.py | Lines ~1115-1191]** `business logic in views`
The `adjust_sections` action contains significant business logic for merging and splitting sections. Per Django review criteria, business logic should live in the service layer (`section_splitting.py`) rather than in views.
---
### 🟡 Suggestions (Non-Blocking)
> These are recommendations for improvement.
- **[File: backend/apps/groups/services/section_splitting.py]** Add docstrings to the `_fetch_chapter_text` and `_estimate_reading_minutes` helper functions.
- **[File: frontend/src/api/groups.ts | Line ~1318]** The `listGroups` API returns either a paginated response or an array; consider adding explicit type guard handling.
- **[File: backend/apps/groups/models.py | Line ~337]** Consider adding a `db_index` to `estimated_reading_minutes` field.
- **[File: backend/apps/groups/views.py | Line ~1242]** The `_renumber_sections` function makes N individual queries for each section. Consider using `bulk_update` for efficiency.
---
### 📋 AC Coverage
> Based on linked issue #29
- [x] Given I am a group admin, When I navigate to the group book section, Then I should see an option to upload an EPUB file.
- [x] Given I have selected an EPUB file to upload, When I confirm the upload, Then the system should parse the EPUB and identify chapter/section boundaries.
- [x] Given the EPUB has been parsed, When I view the section breakdown, Then I should see a list of detected sections with titles and estimated reading time for each.
- [x] Given I am viewing the section breakdown, When I choose to adjust section boundaries, Then I should be able to merge or split sections manually.
- [x] Given the EPUB has been split into sections, When I request section recommendations for meetings, Then the system should suggest which sections to assign to each weekly meeting.
- [ ] Given I have confirmed the section recommendations, When I finalize the group book schedule, Then all group members should be able to see the reading schedule. (BLOCKING: Permission issue)
- [x] Given I am a group admin, When I want to replace the current book, Then I should be able to upload a new EPUB and restart the section splitting process without losing group membership.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Overview
Implements the full Group EPUB Upload and Section Splitting feature (US #29).
Backend (Django)
groupsapp with models: ReadingGroup, GroupBook, Section, ReadingSchedule, MemberProgresssection_splitting.py):GET/POST /api/groups/- List/create reading groupsGET/DELETE /api/groups/:id/- Group detailPOST /api/groups/:id/add_member/andremove_member/- Member managementGET/POST /api/groups/:id/books/- List/upload group booksPOST .../books/:id/detect-sections/- Auto-detect sectionsPOST .../books/:id/adjust-sections/- Manual merge/splitGET/POST/DELETE .../books/:id/schedule/- Reading scheduleGET/PATCH .../books/:id/progress/- Member progressFrontend (React/TypeScript)
/groups) - Create and list reading groups/groups/:id) - Manage members, select and upload EPUB from personal library/groups/:id/books/:id) - Three-tab view:groupsApi), TypeScript types, i18n (en/es)Files changed: 23 files, 2492 insertions
Closes #29
Test comment
Reid's Review — PR #35
Verdict: 🔴 Changes Required
🔴 Blocking Issues
[File: backend/apps/groups/views.py | Line ~942]
missing type hintsThe
IsGroupAdmin.has_permissionandIsGroupAdmin.has_object_permissionmethods useobjectas the type hint for theviewparameter. This should be typed properly per the project's Python 3.10+ type hints standard.[File: backend/apps/groups/views.py | Line ~1218]
missing permission flexibility for progress endpointThe
GroupBookViewSethaspermission_classes = [permissions.IsAuthenticated, IsGroupAdmin]which means only group admins can access the progress endpoint. However, according to AC #6, "when I have confirmed the section recommendations, then all group members should be able to see the reading schedule with target sections per meeting." Members should be able to view and update their own progress, but the current permission class blocks them.[File: frontend/src/pages/GroupBookPage.tsx | Throughout]
inline stylesMultiple React components use inline styles extensively. Per project standards, inline styles are not allowed. Must use CSS modules, styled-components, or a consistent styling solution.
[File: frontend/src/pages/GroupDetailPage.tsx | Throughout]
inline stylesSame inline styles issue as above. All React components have extensive inline styling.
[File: frontend/src/pages/GroupsPage.tsx | Throughout]
inline stylesSame inline styles issue. The entire component uses inline styles.
[File: backend/apps/groups/views.py | Lines ~1115-1191]
business logic in viewsThe
adjust_sectionsaction contains significant business logic for merging and splitting sections. Per Django review criteria, business logic should live in the service layer (section_splitting.py) rather than in views.🟡 Suggestions (Non-Blocking)
[File: backend/apps/groups/services/section_splitting.py] Add docstrings to the
_fetch_chapter_textand_estimate_reading_minuteshelper functions.[File: frontend/src/api/groups.ts | Line ~1318] The
listGroupsAPI returns either a paginated response or an array; consider adding explicit type guard handling.[File: backend/apps/groups/models.py | Line ~337] Consider adding a
db_indextoestimated_reading_minutesfield.[File: backend/apps/groups/views.py | Line ~1242] The
_renumber_sectionsfunction makes N individual queries for each section. Consider usingbulk_updatefor efficiency.📋 AC Coverage