- Consolidate LWWOperationFactory methods (createLWWUpdateOp, mergeAndIncrementClocks) into ConflictResolutionService to reduce service count - Remove redundant caching in SuperSyncProvider (SyncCredentialStore already caches) - Remove _onBlurWhenNotTracking$ sync trigger from SyncTriggerService - Add documentation for dueDay/dueWithTime mutual exclusivity pattern - Change docker-compose postgres port to 55432 to avoid conflicts
4.9 KiB
Architecture Decision Records
This document tracks significant architectural decisions and patterns in the Super Productivity codebase. When making changes that affect these patterns, reference this document and update it if needed.
Active Patterns & Decisions
1. dueDay/dueWithTime Mutual Exclusivity Pattern
Status: ✅ Active (since commit 400ca8c1, 2026-01-29)
Decision: The task.dueDay and task.dueWithTime fields are mutually exclusive in new data. When setting dueWithTime, dueDay must be cleared (set to undefined). When reading, dueWithTime takes priority over dueDay.
Rationale:
- Prevents state inconsistency bugs where both fields had conflicting values
- Single source of truth for task scheduling
- Simpler state management
Implementation:
- Writing: Clear
dueDaywhen settingdueWithTime(in meta-reducers) - Reading: Check
dueWithTimefirst; only checkdueDayifdueWithTimeis not set (in selectors) - Legacy Data: Old data with both fields works via priority pattern (no migration needed)
Documentation: docs/ai/dueDay-dueWithTime-mutual-exclusivity.md
Key Files:
task.model.ts- Field definitions with JSDoctask-shared-scheduling.reducer.ts- Write implementationwork-context.selectors.ts- Read patternplanner.selectors.ts- Read patterntask.selectors.ts- Read pattern
When to Update This Pattern:
- Adding new date/time scheduling fields
- Modifying task scheduling logic
- Working with task selectors that check due dates
2. TODAY_TAG Virtual Tag Pattern
Status: ✅ Active (established pattern)
Decision: TODAY_TAG (ID: 'TODAY') is a virtual tag whose membership is determined by task.dueWithTime or task.dueDay, not by task.tagIds. The tag's taskIds field stores only the ordering of tasks, not membership.
Key Invariant: TODAY_TAG.id must NEVER be added to task.tagIds
Rationale:
- Uniform move operations across all tags (virtual and regular)
- Single source of truth for "today" membership (date fields, not tagIds)
- Self-healing ordering (stale entries automatically filtered)
- Natural integration with planner (which uses date fields)
Documentation: docs/ai/today-tag-architecture.md
Related: Uses the dueDay/dueWithTime mutual exclusivity pattern (Decision #1)
Key Files:
tag.const.ts- TODAY_TAG definitionwork-context.selectors.ts- Membership computationtask-shared-helpers.ts- Invariant enforcement
When to Update This Pattern:
- Adding new virtual tags
- Modifying tag membership logic
- Working with today's task list
How to Use This Document
When Making Architectural Changes
- Before implementing: Check if your change affects any active pattern
- During implementation: Follow the documented patterns
- After implementation: Update this document if you've:
- Changed an existing pattern
- Added a new architectural pattern
- Made a decision that affects future development
When to Add a New Decision
Add a new decision record when:
- The decision affects multiple files/modules
- Future developers need to understand "why" not just "what"
- The pattern needs to be followed consistently across the codebase
- The decision prevents a specific class of bugs
Decision Record Template
### N. [Pattern/Decision Name]
**Status**: ✅ Active | 🚧 Draft | ⚠️ Deprecated | ❌ Superseded
**Decision**: [One-sentence summary of the decision]
**Rationale**:
- [Why was this decision made?]
- [What problems does it solve?]
**Implementation**:
- [How is it implemented?]
- [Key techniques or patterns used]
**Documentation**: [Link to detailed docs]
**Key Files**: [List of primary files implementing this pattern]
**When to Update This Pattern**: [Scenarios when someone should review/update this]
Related Documentation
docs/ai/- AI/Developer architecture docs (detailed patterns)docs/sync-and-op-log/- Operation log architecturedocs/long-term-plans/- Future architectural plans
Commit Reference
When committing changes related to these patterns, reference this document and the specific decision:
feat(tasks): implement feature X
Uses dueDay/dueWithTime mutual exclusivity pattern (ARCHITECTURE-DECISIONS.md #1)
See: docs/ai/dueDay-dueWithTime-mutual-exclusivity.md