
All checks were successful
Deploy to Production, build images and push to Gitea Registry / build_and_push (pull_request) Successful in 1m30s
This commit introduces a detailed roadmap for implementing various features, focusing on backend and frontend improvements. Key additions include: - New database schema designs for financial audit logging, archiving lists, and categorizing items. - Backend logic for financial audit logging, archiving functionality, and chore subtasks. - Frontend UI updates for archiving lists, managing categories, and enhancing the chore interface. - Introduction of a guest user flow and integration of Redis for caching to improve performance. These changes aim to enhance the application's functionality, user experience, and maintainability.
267 lines
14 KiB
Plaintext
267 lines
14 KiB
Plaintext
---
|
|
description:
|
|
globs:
|
|
alwaysApply: false
|
|
---
|
|
Of course. Based on a thorough review of your project's structure and code, here is a detailed, LLM-friendly task list to implement the requested features.
|
|
|
|
This plan is designed to be sequential and modular, focusing on backend database changes first, then backend logic and APIs, and finally the corresponding frontend implementation for each feature.
|
|
|
|
---
|
|
|
|
### **High-Level Strategy & Recommendations**
|
|
|
|
1. **Iterative Implementation:** Tackle one major feature at a time (e.g., complete Audit Logging, then Archiving, etc.). This keeps pull requests manageable and easier to review.
|
|
2. **Traceability:** The request for traceability is key. We will use timestamp-based flags (`archived_at`, `deleted_at`) instead of booleans and create dedicated history/log tables for critical actions.
|
|
|
|
---
|
|
|
|
### **Phase 1: Database Schema Redesign**
|
|
|
|
This is the most critical first step. All subsequent tasks depend on these changes. You will need to create a new Alembic migration to apply these.
|
|
|
|
**File to Modify:** `be/app/models.py`
|
|
**Action:** Create a new Alembic migration file (`alembic revision -m "feature_updates_phase1"`) and implement the following changes in `upgrade()`.
|
|
|
|
**1. Financial Audit Logging**
|
|
* Create a new table to log every financial transaction and change. This ensures complete traceability.
|
|
|
|
```python
|
|
# In be/app/models.py
|
|
class FinancialAuditLog(Base):
|
|
__tablename__ = 'financial_audit_log'
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
timestamp = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=True) # User who performed the action. Nullable for system actions.
|
|
action_type = Column(String, nullable=False, index=True) # e.g., 'EXPENSE_CREATED', 'SPLIT_PAID', 'SETTLEMENT_DELETED'
|
|
entity_type = Column(String, nullable=False) # e.g., 'Expense', 'ExpenseSplit', 'Settlement'
|
|
entity_id = Column(Integer, nullable=False)
|
|
details = Column(JSONB, nullable=True) # To store 'before' and 'after' states or other relevant data.
|
|
|
|
user = relationship("User")
|
|
```
|
|
|
|
**2. Archiving Lists and History**
|
|
* Modify the `lists` table to support soft deletion/archiving.
|
|
|
|
```python
|
|
# In be/app/models.py, class List(Base):
|
|
# REMOVE: is_deleted = Column(Boolean, default=False, nullable=False) # If it exists
|
|
archived_at = Column(DateTime(timezone=True), nullable=True, index=True)
|
|
```
|
|
|
|
**3. Chore Subtasks**
|
|
* Add a self-referencing foreign key to the `chores` table.
|
|
|
|
```python
|
|
# In be/app/models.py, class Chore(Base):
|
|
parent_chore_id = Column(Integer, ForeignKey('chores.id'), nullable=True, index=True)
|
|
|
|
# Add relationships
|
|
parent_chore = relationship("Chore", remote_side=[id], back_populates="child_chores")
|
|
child_chores = relationship("Chore", back_populates="parent_chore", cascade="all, delete-orphan")
|
|
```
|
|
|
|
**4. List Categories**
|
|
* Create a new `categories` table and link it to the `items` table. This allows items to be categorized.
|
|
|
|
```python
|
|
# In be/app/models.py
|
|
class Category(Base):
|
|
__tablename__ = 'categories'
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
name = Column(String, nullable=False, index=True)
|
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=True) # Nullable for global categories
|
|
group_id = Column(Integer, ForeignKey('groups.id'), nullable=True) # Nullable for user-specific or global
|
|
# Add constraints to ensure either user_id or group_id is set, or both are null for global categories
|
|
__table_args__ = (UniqueConstraint('name', 'user_id', 'group_id', name='uq_category_scope'),)
|
|
|
|
# In be/app/models.py, class Item(Base):
|
|
category_id = Column(Integer, ForeignKey('categories.id'), nullable=True)
|
|
category = relationship("Category")
|
|
```
|
|
|
|
**5. Time Tracking for Chores**
|
|
* Create a new `time_entries` table to log time spent on chore assignments.
|
|
|
|
```python
|
|
# In be/app/models.py
|
|
class TimeEntry(Base):
|
|
__tablename__ = 'time_entries'
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
chore_assignment_id = Column(Integer, ForeignKey('chore_assignments.id', ondelete="CASCADE"), nullable=False)
|
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
|
start_time = Column(DateTime(timezone=True), nullable=False)
|
|
end_time = Column(DateTime(timezone=True), nullable=True)
|
|
duration_seconds = Column(Integer, nullable=True) # Calculated on end_time set
|
|
|
|
assignment = relationship("ChoreAssignment")
|
|
user = relationship("User")
|
|
```
|
|
|
|
---
|
|
|
|
### **Phase 2: Backend Implementation**
|
|
|
|
For each feature, implement the necessary backend logic.
|
|
|
|
#### **Task 2.1: Implement Financial Audit Logging**
|
|
|
|
* **Goal:** Automatically log all changes to expenses, splits, and settlements.
|
|
* **Tasks:**
|
|
1. **CRUD (`be/app/crud/audit.py`):**
|
|
* Create a new file `audit.py`.
|
|
* Implement `create_financial_audit_log(db: AsyncSession, user_id: int, action_type: str, entity: Base, details: dict)`. This function will create a new log entry.
|
|
2. **Integrate Logging:**
|
|
* Modify `be/app/crud/expense.py`: In `create_expense`, `update_expense`, `delete_expense`, call `create_financial_audit_log`. For updates, the `details` JSONB should contain `{"before": {...}, "after": {...}}`.
|
|
* Modify `be/app/crud/settlement.py`: Do the same for `create_settlement`, `update_settlement`, `delete_settlement`.
|
|
* Modify `be/app/crud/settlement_activity.py`: Do the same for `create_settlement_activity`.
|
|
3. **API (`be/app/api/v1/endpoints/history.py` - new file):**
|
|
* Create a new endpoint `GET /history/financial/group/{group_id}` to view the audit log for a group.
|
|
* Create a new endpoint `GET /history/financial/user/me` for a user's personal financial history.
|
|
|
|
#### **Task 2.2: Implement Archiving**
|
|
|
|
* **Goal:** Allow users to archive lists instead of permanently deleting them.
|
|
* **Tasks:**
|
|
1. **CRUD (`be/app/crud/list.py`):**
|
|
* Rename `delete_list` to `archive_list`. Instead of `db.delete(list_db)`, it should set `list_db.archived_at = datetime.now(timezone.utc)`.
|
|
* Modify `get_lists_for_user` to filter out archived lists by default: `.where(ListModel.archived_at.is_(None))`.
|
|
2. **API (`be/app/api/v1/endpoints/lists.py`):**
|
|
* Update the `DELETE /{list_id}` endpoint to call `archive_list`.
|
|
* Create a new endpoint `GET /archived` to fetch archived lists for the user.
|
|
* Create a new endpoint `POST /{list_id}/unarchive` to set `archived_at` back to `NULL`.
|
|
|
|
#### **Task 2.3: Implement Chore Subtasks & Unmarking Completion**
|
|
|
|
* **Goal:** Allow chores to have a hierarchy and for completion to be reversible.
|
|
* **Tasks:**
|
|
1. **Schemas (`be/app/schemas/chore.py`):**
|
|
* Update `ChorePublic` and `ChoreCreate` schemas to include `parent_chore_id: Optional[int]` and `child_chores: List[ChorePublic] = []`.
|
|
2. **CRUD (`be/app/crud/chore.py`):**
|
|
* Modify `create_chore` and `update_chore` to handle the `parent_chore_id`.
|
|
* In `update_chore_assignment`, enhance the `is_complete=False` logic. When a chore is re-opened, log it to the history. Decide on the policy for the parent chore's `next_due_date` (recommendation: do not automatically roll it back; let the user adjust it manually if needed).
|
|
3. **API (`be/app/api/v1/endpoints/chores.py`):**
|
|
* Update the `POST` and `PUT` endpoints for chores to accept `parent_chore_id`.
|
|
* The `PUT /assignments/{assignment_id}` endpoint already supports setting `is_complete`. Ensure it correctly calls the updated CRUD logic.
|
|
|
|
#### **Task 2.4: Implement List Categories**
|
|
|
|
* **Goal:** Allow items to be categorized for better organization.
|
|
* **Tasks:**
|
|
1. **Schemas (`be/app/schemas/category.py` - new file):**
|
|
* Create `CategoryCreate`, `CategoryUpdate`, `CategoryPublic`.
|
|
2. **CRUD (`be/app/crud/category.py` - new file):**
|
|
* Implement full CRUD functions for categories (`create_category`, `get_user_categories`, `update_category`, `delete_category`).
|
|
3. **API (`be/app/api/v1/endpoints/categories.py` - new file):**
|
|
* Create endpoints for `GET /`, `POST /`, `PUT /{id}`, `DELETE /{id}` for categories.
|
|
4. **Item Integration:**
|
|
* Update `ItemCreate` and `ItemUpdate` schemas in `be/app/schemas/item.py` to include `category_id: Optional[int]`.
|
|
* Update `crud_item.create_item` and `crud_item.update_item` to handle setting the `category_id`.
|
|
|
|
#### **Task 2.5: Enhance OCR for Receipts**
|
|
|
|
* **skipped**
|
|
|
|
#### **Task 2.6: Implement "Continue as Guest"**
|
|
|
|
* **Goal:** Allow users to use the app without creating a full account.
|
|
* **Tasks:**
|
|
1. **DB Model (`be/app/models.py`):**
|
|
* Add `is_guest = Column(Boolean, default=False, nullable=False)` to the `User` model.
|
|
2. **Auth (`be/app/api/auth/guest.py` - new file):**
|
|
* Create a new router for guest functionality.
|
|
* Implement a `POST /auth/guest` endpoint. This endpoint will:
|
|
* Create a new user with a unique but temporary-looking email (e.g., `guest_{uuid}@guest.mitlist.app`).
|
|
* Set `is_guest=True`.
|
|
* Generate and return JWT tokens for this guest user, just like a normal login.
|
|
3. **Claim Account (`be/app/api/auth/guest.py`):**
|
|
* Implement a `POST /auth/guest/claim` endpoint (requires auth). This endpoint will take a new email and password, update the `is_guest=False`, set the new credentials, and mark the email for verification.
|
|
|
|
#### **Task 2.7: Implement Redis**
|
|
|
|
* **Goal:** Integrate Redis for caching to improve performance.
|
|
* **Tasks:**
|
|
1. **Dependencies (`be/requirements.txt`):** Add `redis`.
|
|
2. **Configuration (`be/app/config.py`):** Add `REDIS_URL` to settings.
|
|
3. **Connection (`be/app/core/redis.py` - new file):** Create a Redis connection pool.
|
|
4. **Caching (`be/app/core/cache.py` - new file):** Implement a simple caching decorator.
|
|
```python
|
|
# Example decorator
|
|
def cache(expire_time: int = 3600):
|
|
def decorator(func):
|
|
@wraps(func)
|
|
async def wrapper(*args, **kwargs):
|
|
# ... logic to check cache, return if hit ...
|
|
# ... if miss, call func, store result in cache ...
|
|
return result
|
|
return wrapper
|
|
return decorator
|
|
```
|
|
5. **Apply Caching:** Apply the `@cache` decorator to read-heavy, non-volatile CRUD functions like `crud_group.get_group_by_id`.
|
|
|
|
---
|
|
|
|
### **Phase 3: Frontend Implementation**
|
|
|
|
Implement the UI for the new features, using your Valerie UI components.
|
|
|
|
#### **Task 3.1: Implement Archiving UI**
|
|
|
|
* **Goal:** Allow users to archive and view archived lists.
|
|
* **Files to Modify:** `fe/src/pages/ListsPage.vue`, `fe/src/stores/listStore.ts` (if you create one).
|
|
* **Tasks:**
|
|
1. Change the "Delete" action on lists to "Archive".
|
|
2. Add a toggle/filter to show archived lists.
|
|
3. When viewing archived lists, show an "Unarchive" button.
|
|
|
|
#### **Task 3.2: Implement Subtasks and Unmarking UI**
|
|
|
|
* **Goal:** Update the chore interface for subtasks and undoing completion.
|
|
* **Files to Modify:** `fe/src/pages/ChoresPage.vue`, `fe/src/components/ChoreItem.vue` (if it exists).
|
|
* **Tasks:**
|
|
1. Modify the chore list to be a nested/tree view to display parent-child relationships.
|
|
2. Update the chore creation/edit modal to include a "Parent Chore" dropdown.
|
|
3. On completed chores, change the "Completed" checkmark to an "Undo" button. Clicking it should call the API to set `is_complete` to `false`.
|
|
|
|
#### **Task 3.3: Implement Category Management and Supermarkt Mode**
|
|
|
|
* **Goal:** Add category features and the special "Supermarkt Mode".
|
|
* **Files to Modify:** `fe/src/pages/ListDetailPage.vue`, `fe/src/components/Item.vue`.
|
|
* **Tasks:**
|
|
1. Create a new page/modal for managing categories (CRUD).
|
|
2. In the `ListDetailPage`, add a "Category" dropdown when adding/editing an item.
|
|
3. Display items grouped by category.
|
|
4. **Supermarkt Mode:**
|
|
* Add a toggle button on the `ListDetailPage` to enter "Supermarkt Mode".
|
|
* When an item is checked, apply a temporary CSS class to other items in the same category.
|
|
* Ensure the price input field appears next to checked items.
|
|
* Add a `VProgressBar` at the top, with `value` bound to `completedItems.length` and `max` bound to `totalItems.length`.
|
|
|
|
#### **Task 3.4: Implement Time Tracking UI**
|
|
|
|
* **Goal:** Allow users to track time on chores.
|
|
* **Files to Modify:** `fe/src/pages/ChoresPage.vue`.
|
|
* **Tasks:**
|
|
1. Add a "Start/Stop" timer button on each chore assignment.
|
|
2. Clicking "Start" sends a `POST /time_entries` request.
|
|
3. Clicking "Stop" sends a `PUT /time_entries/{id}` request.
|
|
4. Display the total time spent on the chore.
|
|
|
|
|
|
#### **Task 3.5: Implement Guest Flow**
|
|
|
|
* **Goal:** Provide a seamless entry point for new users.
|
|
* **Files to Modify:** `fe/src/pages/LoginPage.vue`, `fe/src/stores/auth.ts`, `fe/src/router/index.ts`.
|
|
* **Tasks:**
|
|
1. On the `LoginPage`, add a "Continue as Guest" button.
|
|
2. This button calls a new `authStore.loginAsGuest()` action.
|
|
3. The action hits the `POST /auth/guest` endpoint, receives tokens, and stores them.
|
|
4. The router logic needs adjustment to handle guest users. You might want to protect certain pages (like "Account Settings") even from guests.
|
|
5. Add a persistent banner in the UI for guest users: "You are using a guest account. **Sign up** to save your data."
|
|
|
|
</file>
|
|
```
|
|
|
|
|
|
**Final Note:** This is a comprehensive roadmap. Each major task can be broken down further into smaller sub-tasks. Good luck with the implementation |