Skip to content

Commit 13da690

Browse files
authored
Merge pull request #7 from zooper-lib/feature/stash
No idea what I did recently
2 parents cbc9bc3 + 4b8f6d8 commit 13da690

132 files changed

Lines changed: 3357 additions & 1786 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/instructions/instructions.instructions.md

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
---
2+
name: doc-comments
3+
description: Guidelines for writing documentation comments and inline comments in Dart/Flutter code. Use when documenting classes, methods, providers, errors, or writing inline comments. Enforces principles like avoiding usage examples, avoiding 'typically used by' sections, avoiding step numbers in comments, and focusing on contracts over usage.
4+
---
5+
6+
# Documentation and Comment Guidelines
7+
8+
## When to Use This Skill
9+
10+
Use this skill when:
11+
- Writing doc comments for classes, interfaces, methods, or functions
12+
- Documenting error types and their cases
13+
- Creating provider documentation
14+
- Writing inline comments in implementation code
15+
- Reviewing or improving existing documentation
16+
17+
## Core Principles
18+
19+
1. **Be Descriptive, Not Prescriptive**: Explain what something does and why it exists, not how to use it
20+
2. **Document Contracts**: Focus on inputs, outputs, errors, and behavior
21+
3. **Avoid Redundancy**: Don't duplicate information available through IDE features (type hints, autocomplete, Find Usages)
22+
4. **Prevent Staleness**: Avoid documentation that becomes obsolete with code changes
23+
5. **Add Value**: Only document what provides genuine insight beyond the code itself
24+
25+
## What NOT to Include in Documentation
26+
27+
### ❌ Usage Examples
28+
29+
Never include code examples showing how to use the documented element.
30+
31+
**Why:** Usage examples become outdated quickly and are redundant with IDE autocomplete and type information.
32+
33+
**Bad:**
34+
```dart
35+
/// Provider for the audio file validation use case.
36+
///
37+
/// Usage example:
38+
/// ```dart
39+
/// final useCase = ref.read(validateAudioFileUseCaseProvider);
40+
/// final result = await useCase(file: File('/path/to/audio.mp3'));
41+
/// ```
42+
final validateAudioFileUseCaseProvider = Provider<ValidateAudioFileUseCase>(...);
43+
```
44+
45+
**Good:**
46+
```dart
47+
/// Provider for the audio file validation use case.
48+
///
49+
/// Provides an instance of [ValidateAudioFileUseCase] that validates
50+
/// whether a file exists, is accessible, and can be read. The use case is
51+
/// stateless and can be safely shared across the application.
52+
final validateAudioFileUseCaseProvider = Provider<ValidateAudioFileUseCase>(...);
53+
```
54+
55+
### ❌ "Typically Used By" Sections
56+
57+
Never list which parts of the codebase use the documented element.
58+
59+
**Why:** Dependencies change frequently, and the IDE's "Find Usages" feature provides this information dynamically.
60+
61+
**Bad:**
62+
```dart
63+
/// Provider for the file accessibility validation use case.
64+
///
65+
/// This provider is typically used by:
66+
/// - Import workflows to pre-validate files before processing
67+
/// - Controllers that need to verify file accessibility before operations
68+
/// - Background services that check file integrity
69+
final validateFileAccessibilityUseCaseProvider = Provider<ValidateFileAccessibilityUseCase>(...);
70+
```
71+
72+
**Good:**
73+
```dart
74+
/// Provider for the file accessibility validation use case.
75+
///
76+
/// Provides an instance of [ValidateFileAccessibilityUseCase] that validates
77+
/// whether a file exists, is accessible, and can be read.
78+
final validateFileAccessibilityUseCaseProvider = Provider<ValidateFileAccessibilityUseCase>(...);
79+
```
80+
81+
### ❌ Step Numbers in Inline Comments
82+
83+
Never number sequential steps in implementation code.
84+
85+
**Why:** Step numbers become obsolete when steps are added, removed, or reordered.
86+
87+
**Bad:**
88+
```dart
89+
Future<Either<Error, Result>> process() async {
90+
// Step 1: Validate input
91+
final validationResult = await _validate();
92+
93+
// Step 2: Process data
94+
final processResult = await _process();
95+
96+
// Step 3: Save result
97+
await _save(processResult);
98+
}
99+
```
100+
101+
**Good:**
102+
```dart
103+
Future<Either<Error, Result>> process() async {
104+
// Validate input parameters and file accessibility
105+
final validationResult = await _validate();
106+
107+
// Process data and transform to domain model
108+
final processResult = await _process();
109+
110+
// Persist result to repository
111+
await _save(processResult);
112+
}
113+
```
114+
115+
## What to Include in Documentation
116+
117+
### Class/Interface Documentation
118+
119+
Document:
120+
- The purpose and responsibility
121+
- Key behaviors and workflows
122+
- What it does NOT do (if relevant for clarity)
123+
- State management characteristics (stateless, immutable, etc.)
124+
125+
**Example:**
126+
```dart
127+
/// Use case for validating that a file is accessible and suitable for import.
128+
///
129+
/// This use case performs filesystem I/O checks to guard against common issues
130+
/// that would prevent successful file processing:
131+
/// - File does not exist at the specified path
132+
/// - Path points to a directory or other non-file entity
133+
/// - File exists but is empty (0 bytes)
134+
/// - Insufficient permissions to read the file
135+
/// - File is locked by another process
136+
///
137+
/// The validation includes:
138+
/// 1. Existence check
139+
/// 2. Entity type verification (must be a file, not a directory)
140+
/// 3. Size verification (must be non-empty)
141+
/// 4. Read accessibility test (attempts to open and immediately close)
142+
abstract interface class ValidateFileAccessibilityUseCase { ... }
143+
```
144+
145+
### Method Documentation
146+
147+
Document:
148+
- Brief description of what the method does
149+
- Parameters with their purpose and constraints
150+
- Return values and their meaning
151+
- Error conditions (when Left/exceptions are returned)
152+
- Side effects and I/O operations
153+
- Important notes about behavior
154+
155+
**Example:**
156+
```dart
157+
/// Validates that the specified [file] is accessible and suitable for processing.
158+
///
159+
/// Performs a series of checks to ensure the file:
160+
/// - Exists on the filesystem
161+
/// - Is a regular file (not a directory or link)
162+
/// - Has non-zero size
163+
/// - Can be opened for reading
164+
///
165+
/// Parameters:
166+
/// - [file]: The file to validate
167+
///
168+
/// Returns:
169+
/// - [Right] with `void` if the file passes all validation checks
170+
/// - [Left] with [ValidateFileAccessibilityError] describing the specific issue
171+
///
172+
/// Note: This method performs I/O operations and should be called from
173+
/// an async context. The read accessibility test opens the file briefly
174+
/// but does not read its contents.
175+
Future<Either<ValidateFileAccessibilityError, void>> call({
176+
required File file,
177+
});
178+
```
179+
180+
### Error Type Documentation
181+
182+
Document each error case with:
183+
- What the error represents
184+
- When/why it occurs (specific conditions)
185+
- User action or recovery path (if applicable)
186+
187+
**Example:**
188+
```dart
189+
@freezed
190+
/// Error returned when file accessibility validation fails.
191+
///
192+
/// These error types represent specific, actionable failure modes that can
193+
/// occur when validating file accessibility. Each error type maps to a
194+
/// distinct user-facing message and potential recovery action.
195+
sealed class ValidateFileAccessibilityError with _$ValidateFileAccessibilityError {
196+
/// The specified file does not exist at the given path.
197+
///
198+
/// This error occurs when:
199+
/// - The file path is invalid or incorrect
200+
/// - The file was deleted after being selected
201+
///
202+
/// User action: Verify the file path or select the file again.
203+
const factory ValidateFileAccessibilityError.fileNotFound() = _FileNotFound;
204+
205+
/// Access to the file was denied due to insufficient permissions.
206+
///
207+
/// This error occurs when:
208+
/// - The application lacks read permissions for the file
209+
/// - The file is in a protected system directory
210+
///
211+
/// User action: Grant the application necessary file access permissions.
212+
const factory ValidateFileAccessibilityError.permissionDenied() = _PermissionDenied;
213+
}
214+
```
215+
216+
### Provider Documentation
217+
218+
Document:
219+
- What the provider provides (be specific about the implementation)
220+
- Key characteristics (stateless, singleton, etc.)
221+
222+
**Example:**
223+
```dart
224+
/// Provider for the audio file discovery use case.
225+
///
226+
/// Provides an instance of [DiscoverAudioFilesInDirectoryUseCase] that scans
227+
/// directories for audio files. The use case is stateless and can be safely
228+
/// shared across the application.
229+
final discoverAudioFilesInDirectoryUseCaseProvider =
230+
Provider<DiscoverAudioFilesInDirectoryUseCase>(
231+
(ref) => const DiscoverAudioFilesInDirectoryUseCaseImpl(),
232+
);
233+
```
234+
235+
### Implementation Class Documentation
236+
237+
Document:
238+
- High-level description of the implementation approach
239+
- Key algorithms or patterns used
240+
- State management and thread-safety characteristics
241+
242+
**Example:**
243+
```dart
244+
/// Default implementation of [CreateAudioFileWorkflow].
245+
///
246+
/// This implementation orchestrates the audio file creation process by:
247+
/// 1. Validating file accessibility and format using dedicated use cases
248+
/// 2. Allocating a sequential file number from the repository
249+
/// 3. Creating the domain aggregate via domain events
250+
/// 4. Persisting the aggregate through the repository
251+
/// 5. Publishing domain events to the event bus
252+
///
253+
/// The workflow maintains transactional consistency by validating all inputs
254+
/// before making changes, committing modifications atomically, and publishing
255+
/// events only after successful persistence.
256+
final class CreateAudioFileWorkflowImpl implements CreateAudioFileWorkflow {
257+
// ...
258+
}
259+
```
260+
261+
Note: Numbered lists are acceptable in class-level documentation when describing architecture or design, not sequential code steps.
262+
263+
### Inline Comments
264+
265+
Use descriptive comments that:
266+
- Explain **what** the code block does
267+
- Add context that isn't obvious from the code itself
268+
- Clarify **why** something is done a certain way (if non-obvious)
269+
- Note important behavioral details or constraints
270+
271+
**Good Examples:**
272+
```dart
273+
// Check if the file exists on the filesystem
274+
if (!await file.exists()) {
275+
return const Left(ValidateFileAccessibilityError.fileNotFound());
276+
}
277+
278+
// Verify that the path points to a file, not a directory or other entity
279+
final fileStatistics = await file.stat();
280+
281+
// Attempt to open the file for reading to verify accessibility.
282+
// This will fail if the file is locked or permissions are insufficient.
283+
final randomAccessFile = await file.open(mode: FileMode.read);
284+
await randomAccessFile.close();
285+
```
286+
287+
### Private Method Documentation
288+
289+
Private methods should have doc comments if they:
290+
- Have non-trivial logic
291+
- Are reused across the class
292+
- Have parameters that need explanation
293+
294+
**Example:**
295+
```dart
296+
/// Maps a [FileSystemException] to a use-case-specific error type.
297+
///
298+
/// Examines the OS error code from the exception and translates it into
299+
/// one of the domain-specific error types based on common POSIX and Windows codes:
300+
/// - `2` (ENOENT): File not found
301+
/// - `13` (EACCES) or `5` (Windows): Permission denied
302+
/// - `11` (EAGAIN) or `35` (macOS): File locked
303+
///
304+
/// Parameters:
305+
/// - [e]: The filesystem exception to map
306+
///
307+
/// Returns the appropriate [ValidateFileAccessibilityError] subtype.
308+
ValidateFileAccessibilityError _mapFileSystemException(FileSystemException e) {
309+
// ...
310+
}
311+
```
312+
313+
## Quick Review Checklist
314+
315+
When writing documentation, verify:
316+
- [ ] Explains the purpose and responsibility
317+
- [ ] Documents all parameters and return values
318+
- [ ] Explains error conditions
319+
- [ ] NO usage examples included
320+
- [ ] NO "typically used by" lists
321+
- [ ] NO step numbers in inline comments
322+
- [ ] Is maintainable as code evolves
323+
- [ ] Adds value beyond code and types
324+
325+
## Summary
326+
327+
Focus on documenting **contracts** (what, parameters, returns, errors) rather than **usage** (how to call, who uses it). Keep documentation maintainable by avoiding elements that become stale with code changes like usage examples, consumer lists, and step numbers.
328+

0 commit comments

Comments
 (0)