[CS2113-W13-1] ZettelCLI#41
Conversation
…-command Feature: Implement ExitCommand
For example, if attempting to open vim from IntelliJ Idea's Run, a pseudoconsole
…into 79-feat-unlink-notes
Add feature to unlink notes
…tadata, added noteserializer test and jdocs for storage classes
…efore NoEditorFound
Feature: add deleteNoteCommand functionality to delete body file + me…
…directions Feature: Unlink any 2 notes in both directions with 1 command
duckyfuz
left a comment
There was a problem hiding this comment.
Would it be good to add instructions for manual testing?
| ├─ Read User Input (with timeout) | ||
| ├─ Parse Command | ||
| ├─ Execute Command | ||
| ├─ Auto-save Notes |
There was a problem hiding this comment.
I see Auto-save Notes is listed as a step inside the main loop. Does this imply it runs after every single command, even read-only ones?
| - Handle graceful shutdown and error recovery | ||
| - Auto-save notes after each command | ||
|
|
||
| **Main Application Flow:** |
There was a problem hiding this comment.
Have you considered using a tool like PlantUML (puml) to generate this diagram instead of typing it out manually?
It might make it much easier to maintain, version control alongside your code, and embed directly into documentation (like in a README.md). For a process flow like this, you could use an activity diagram, which would also make modeling the loop and any conditional logic explicit.
| **Class Diagram:** | ||
| ``` | ||
| ┌─────────────────────────┐ | ||
| │ Zettel │ | ||
| ├─────────────────────────┤ | ||
| │ - storage: Storage │ | ||
| │ - notes: ArrayList │ | ||
| │ - ui: UI │ | ||
| │ - isRunning: boolean │ | ||
| ├─────────────────────────┤ | ||
| │ + run(): void │ | ||
| │ + main(String[]): void │ | ||
| └─────────────────────────┘ | ||
| ``` |
There was a problem hiding this comment.
Just like with the activity diagram, have you considered generating this class diagram with PlantUML? It's excellent for keeping your diagrams in sync with your code, as you can just edit the text source.
This syntax also makes it very easy to add relationship lines, like associations to the Storage and UI classes, or composition if Zettel "owns" the notes.
| Input: pin a1b2c3d4 | ||
| ↓ | ||
| [Validation 1] Format Check | ||
| ├─ Length = 8? ✓ | ||
| ├─ Matches [a-f0-9]? ✓ | ||
| └─ Pass → Continue | ||
| ↓ | ||
| [Validation 2] Empty List Check | ||
| ├─ notes.isEmpty()? | ||
| ├─ If true → throw NoNotesException | ||
| └─ If false → Continue | ||
| ↓ | ||
| [Validation 3] Note Existence Check | ||
| ├─ Find note with ID | ||
| ├─ If not found → throw InvalidNoteIdException | ||
| └─ If found → Continue | ||
| ↓ | ||
| [Validation 4] State Check | ||
| ├─ Is note.isPinned() == isPin? | ||
| ├─ If true → throw AlreadyPinnedException | ||
| └─ If false → Continue | ||
| ↓ | ||
| [Happy Path] Execute Operation | ||
| ├─ Get note from Optional | ||
| ├─ Set pinned status | ||
| ├─ Display confirmation | ||
| └─ Save to storage | ||
| ``` |
There was a problem hiding this comment.
As with the other diagrams, have you considered using a PlantUML activity diagram?
It's particularly good at showing this kind of "guard clause" or "fail-fast" pattern, where each if statement acts as a gate that the logic must pass through.
This way, the different paths (the happy path vs. the various error exceptions) can all be visualized very clearly.
| **Sequence Diagram - Pin Note Operation:** | ||
|
|
||
| ``` | ||
| User → Parser → PinNoteCommand → Notes → Note → UI → Storage | ||
| | | | | | | | | ||
| | pin a1b2c3d4 | | | | | | ||
| |------>| | | | | | | ||
| | | new PinNoteCommand | | | | | ||
| | |----------->| | | | | | ||
| | | | | | | | | ||
| | | execute()| | | | | | ||
| | |----------->| | | | | | ||
| | | | validateFormat() | | | | ||
| | | |---- | | | | | ||
| | | | | | | | | | ||
| | | |<---- | | | | | ||
| | | | isEmpty()? | | | | | ||
| | | |----------->| | | | | ||
| | | |<-----------| | | | | ||
| | | | stream() | | | | | ||
| | | | filter() | | | | | ||
| | | | findFirst()| | | | | ||
| | | |----------->| | | | | ||
| | | |<-----------| | | | | ||
| | | | | | | | ||
| | | | get() | | | | ||
| | | |------------------>| | | |
There was a problem hiding this comment.
Same here, have you considered using a UML diagram?
Additionally, should there be arrows pointing from class to class?
eg. in the first line
User → Parser → PinNoteCommand → Notes → Note → UI → Storage
| **Class Diagram:** | ||
| ``` | ||
| ┌─────────────────────────────────┐ | ||
| │ Note │ | ||
| ├─────────────────────────────────┤ | ||
| │ - id: String (8 chars) │ | ||
| │ - title: String │ | ||
| │ - filename: String │ | ||
| │ - body: String │ | ||
| │ - createdAt: Instant │ | ||
| │ - modifiedAt: Instant │ | ||
| │ - pinned: boolean │ | ||
| │ - archived: boolean │ | ||
| │ - archiveName: String │ | ||
| │ - logs: List<String> │ | ||
| │ - numberOfNotes: int (static) │ | ||
| ├─────────────────────────────────┤ | ||
| │ + Note(id, title, ...) │ | ||
| │ + getId(): String │ | ||
| │ + getTitle(): String │ | ||
| │ + setTitle(String): void │ | ||
| │ + setPinned(boolean): void │ | ||
| │ + addLog(String): void │ | ||
| │ + updateModifiedAt(): void │ | ||
| │ + toString(): String │ | ||
| └─────────────────────────────────┘ | ||
| ``` |
There was a problem hiding this comment.
Similarly, have you considered using a UML diagram for this?
Perhaps showing all classes in a overview UML diagram, then "zooming in" on each class would provide a clearer view of how the classes relate to each other.
| │ - logs: List<String> │ | ||
| │ - numberOfNotes: int (static) │ | ||
| ├─────────────────────────────────┤ | ||
| │ + Note(id, title, ...) │ |
There was a problem hiding this comment.
What other params does the constructor take in?
Additionally, for overloaded methods, would it be better to list each overloaded operation individually instead of using ellipsis?
Perhaps a UML diagram would be better here, as each line can be longer without you having to worry about the formatting of the box.
I see that the Note constructor takes in many params.
| │ - archived: boolean │ | ||
| │ - archiveName: String │ | ||
| │ - logs: List<String> │ | ||
| │ - numberOfNotes: int (static) │ |
There was a problem hiding this comment.
Is this the correct notation for indicating static methods?
| - All I/O operations wrapped in try–catch | ||
| - On failure: print readable warning (no crash) | ||
| - Missing folders/files are auto-created | ||
| - Corrupted index entries are skipped (with console notice) |
There was a problem hiding this comment.
Regarding the "Corrupted index entries are skipped": When a corrupted entry is found and skipped, is it just for that one session? Or does your app perhaps quarantine it or mark it as "corrupted" so it doesn't try to parse it (and log a notice) every single time the app starts?
| │ - logger: Logger │ | ||
| ├─────────────────────────────────┤ | ||
| │ + PinNoteCommand(String, bool) │ | ||
| │ + execute(ArrayList, UI, ...) │ |
Docs: Update tag jdoc
Update DeveloperGuide for v2.1
Fix: init validation and tests
Modify PPP, @@author a few Storage methods
Update user guide and note.java
Fix: AboutUs.md broken links
…into add-DG-implementation
Change press y to Press y/Y
…into add-DG-implementation
Add dg implementation
Update DG and UG
Update shira421.md




ZettelCLI is a desktop Command Line Interface (CLI) application used for managing a personal Zettlekesten note system. It is optimised for users who prefer keyboard commands over Graphical User Interfaces (GUI). Through just a keyboard, users can build their own repository of notes or quickly navigate through their knowledge base with ease.