Refactor: Reorganize data access with simplified clean architecture#39
Refactor: Reorganize data access with simplified clean architecture#39Copilot wants to merge 4 commits into
Conversation
…tation Co-authored-by: pablonete <579705+pablonete@users.noreply.github.com>
Co-authored-by: pablonete <579705+pablonete@users.noreply.github.com>
|
|
||
| /** | ||
| * Save cashflow for a specific quarter | ||
| * Note: Actual saving is coordinated through the DataContext's commit mechanism |
There was a problem hiding this comment.
The main value the repository class should offer is keeping track of loaded files, and replace them with "dirty versions" until they are saved in a commit.
So the save should not exist here as "commit changes" but there should be an update method that "saves to memory" the file content, which then is declared as dirty, and that later is read by the actual saving logic to "commit changes".
| /** | ||
| * Load cashflow for a specific quarter | ||
| */ | ||
| async load(quarterId: string): Promise<FileResult<CashflowFileData>> { |
There was a problem hiding this comment.
Based on my previous comment, load should not always be "fetching" but sometimes return the content from memory if it was already loaded or it was created in memory. Let's rename accordingly to getContent, and then the complementary method may be updateContent.
- Combine 3 repository classes into single QuarterFileRepository with generics - Rename commitError -> globalError for broader usage - Replace loadInvoices/loadExpenses/loadCashflow with unified getFile(quarterId, type) - Replace getEditingFile with isDirtyFile() for cleaner API - Rename setEditingFile -> updateFile - Add companyName to useData() to avoid exposing activeStorage - Add getFileUrl() to useData() scoped to current storage - Update all components to use new simplified API Co-authored-by: pablonete <579705+pablonete@users.noreply.github.com>
Done in e066314. Simplified the API significantly:
Regarding comments about repository tracking loaded/dirty files (2821135877, 2821141717): The current implementation already handles this in DataContext. The repository's role is just to fetch from GitHub - the context tracks which files are loaded vs dirty and returns the appropriate version. This keeps repositories simple and focused. Let me know if you'd like me to restructure this differently. |
Storage files were scattered across
lib/with React Query exposed directly to components. This reorganizes data access into a three-layer architecture with a simplified, unified API.Structure
API Changes
Before:
After:
Key Improvements
getFile(): Single method replacesloadInvoices(),loadExpenses(),loadCashflow()using TypeScript genericsisDirtyFile()hides internal editing state,updateFile()replacessetEditingFile()companyNameandgetFileUrl()from context, no need to passstoragepropsQuarterFileRepository<T>replaces 3 duplicate repository classesglobalErrorreplacescommitErrorfor broader usageImplementation
QuarterFileRepository<T>handles all file types (invoices, expenses, cashflow) with type safetyDataProvidercombines storage selection, editing state, and data fetching with React Query fully encapsulatedFiles
Removed (11):
storage-context.tsx,editing-state-context.tsx,use-storage-data.ts,use-storage-quarters.ts,github-data.ts,github-storage.ts,storage-persistence.ts,storage-types.ts,invoices-repository.ts,expenses-repository.ts,cashflow-repository.tsAdded (6): Architecture doc with Mermaid diagram, unified context, generic repository, 3 infrastructure modules, clean export interface
Updated (12 components): All migrated to simplified
useData()APIArchitecture documentation with persistence flow diagrams in
lib/data/DATA_ARCHITECTURE.md.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.