Skip to content

ZCW-Fall25/Notes-future-proof

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

future-proof

Build a Personal Notes Manager

A multi-phase educational project for managing personal notes with structured metadata.

It is also the first time we consider the idea of future-proof software.

Overview

Personal Notes Manager is a text-based note-taking system that stores notes as UTF-8 text files with YAML headers for metadata. This project serves as an educational tool for students to learn file manipulation, parsing, and progressively more advanced application architectures.

https://zcw.guru/kristofer/javapygitignore

Future-Proof software

"Future-proof" software is code designed to remain useful, maintainable, and adaptable as technology evolves and requirements change over time. Think of it like building a house with a strong foundation that can support renovations and additions years later.

Why future-proofing matters: When you write software, you're not just solving today's problem - you're creating something that will likely need to change. User needs evolve, new technologies emerge, and business requirements shift. Future-proof code makes these inevitable changes easier and less expensive.

Key principles for future-proof software:

Modularity and separation of concerns - Break your code into distinct, focused pieces that do one thing well. If you need to change how data is stored, you shouldn't have to rewrite your user interface code too. If you store your notes in text files now, but a database in the next version, how do you make sure you can move amongst different storage tech?

Use established standards and conventions - Following widely-adopted patterns means other developers can understand your code, and it's more likely to work well with future tools and libraries. And text files, based on UNICODE, is one of the most well-respected storage modalities. (So is Sqlite3, see Library of Congress; Recommended Formats Statement)

Avoid hard-coding values - Instead of writing if (users.length > 100), use a configurable constant like if (users.length > MAX_USERS). This makes it easy to adjust limits without hunting through code. These items can be kept together, so that they can be reviewed and changed as needed in Future YEARS.

Choose stable, well-supported technologies - While it's tempting to use the newest framework, mature technologies with strong communities tend to have better long-term support.

Write clear documentation and tests - Future you (or other developers) will thank you when they need to modify code written months or years ago. So, unit tests and test-driven development is a critical part of this project. Test early and often. And make sure your Future You knows how to run the test and read the comments and PLAN and SPEC documents.

The goal isn't to predict the future perfectly, but to write code that bends rather than breaks when change inevitably comes. It's about making smart trade-offs between solving immediate needs and maintaining flexibility for tomorrow's challenges.

Project Phases

This project is designed to be implemented in three distinct phases:

Phase 1: Command Line Interface (CLI)

  • Basic note creation, reading, updating, and deletion via command line
  • YAML header parsing and manipulation
  • Note searching and filtering capabilities
  • Simple formatting options

Phase 2: Graphical User Interface (GUI)

  • Desktop application with intuitive UI
  • Rich text editing features
  • Visual organization of notes (folders/tags)
  • Enhanced search functionality with highlighting
  • Export options (PDF, HTML, etc.)

Phase 3: REST Server with JavaScript Frontend

  • Web-based access to notes
  • Multi-user support with authentication
  • Real-time collaborative editing
  • Mobile-responsive design
  • API documentation for potential extensions

File Structure

Notes are stored as plain text files with a .note extension (or any extension you prefer). Each note follows this structure:

---
title: My Example Note
created: 2025-05-20T10:30:00Z
modified: 2025-05-20T10:45:00Z
tags: [example, documentation]
---

This is the content of my note.
It can contain multiple paragraphs and basic formatting.

You can include lists:
- Item 1
- Item 2
- Item 3

And other simple markdown markup as needed.

YAML Header Specification

The YAML header is delimited by triple dashes (---) and contains metadata about the note:

Field Description Type Required
title The title of the note String Yes
created Creation timestamp (ISO 8601) DateTime Yes
modified Last modification timestamp (ISO 8601) DateTime Yes
tags Categories or labels for the note Array of Strings No
author Creator of the note String No
status Completion or review status String No
priority Importance level Integer (1-5) No

Additional custom fields can be added as needed.

There a few sample note files in test-notes/

Phase 1: CLI Implementation

Command Reference

notes --help                     # Display help information
notes create                     # Create a new note (opens in default editor)
notes list                       # List all notes
notes list --tag "coursework"    # List notes with specific tag
notes read <note-id>             # Display a specific note
notes edit <note-id>             # Edit a specific note
notes delete <note-id>           # Delete a specific note
notes search "query"             # Search notes for text (title, tags, content)
notes stats                      # Display statistics about your notes

Technical Requirements

  • Java 11+ or Python 3.11+
  • YAML parser library
  • Filesystem access & manipulation
  • Text editor integration (nano?)
  • Extra Credit: github integration for the notes storage
  • Extra Credit: note encryption (and key management)

Phase 2: GUI Implementation

Maybe this week, maybe next time we come back around to this project.

Features

  • Note browser panel (folder structure or tag-based)
  • Rich text editor with markdown support
  • Real-time preview
  • Drag and drop organization
  • Dark/light theme options
  • Backup and restore functionality

Technical Requirements

  • Java Swing or TKinter
  • HTML/CSS for UI (if using web technologies)
  • Local storage management
  • Cross-platform compatibility

Phase 3: REST Server Implementation

Maybe instead of Phase 2? Maybe this week, maybe in the future.

What is this stuff anyway? Well, Ask your friendly, globe-girdling AI.

API Endpoints

GET    /api/notes                # List all notes
POST   /api/notes                # Create a new note
GET    /api/notes/:id            # Retrieve a specific note
PUT    /api/notes/:id            # Update a specific note
DELETE /api/notes/:id            # Delete a specific note
GET    /api/tags                 # List all tags
GET    /api/notes/tag/:tagid          # List all notes with tag tagid
GET    /api/search?q=query       # Search notes

Technical Requirements

  • Express.js/Flask/Django REST framework (python)
  • Spring/Springboot
  • Frontend: VanillaJS (first)
  • Frontend: React/Vue/Angular?
  • Authentication system (don't want just anyone reading your notes)
  • Database integration (optional, should still use file system)
  • API documentation (Swagger/OpenAPI)

Learning Objectives

Students will gain experience with:

  1. File I/O operations
  2. Data parsing and validation
  3. Command-line argument processing
  4. User interface design principles
  5. Client-server architecture
  6. REST API development
  7. Frontend-backend integration
  8. Project planning and progressive enhancement

Getting Started

Prerequisites

  • [List required software/libraries]
  • Basic understanding of Java or Python
  • Knowledge of [relevant concepts]

Installation

# Clone the repository
# CHOOSE your Project's Name NOW.... _don't use future-proof_.
git clone https://github.com/yourusername/future-proof.git

# Navigate to the project directory or whatever you named it in the clone.
cd `yournotesnamehere`

# Install dependencies
(if you need them)

# Run the application
run.sh

Contributing

This project is designed for educational purposes. Students are encouraged to:

  1. Fork the repository
  2. Create a feature branch
  3. Implement their assigned component
  4. Submit a pull request for review

License

[MIT license]

Acknowledgments

  • Every amazing personal notes project out there.
  • Unix file system. Without it, we'd be sunk.
  • Markdown: the way techies write.

Possible Project Names

Possible Names for your version of this project (or make up your own!)

NoteNexus MindScribe ThoughtVault StudyStream MemoPad Pro BrainWave Notes Scholarly Jotter InsightKeeper Knowledge Capsule NoteCraft MindMapper StudyPulse ThoughtHub NoteWorthy IdeaTracker StudySync RecallPro ClassCompass MindfulNotes LearnLogger

But I wanna do a databse "NOW!!!"

Why Build Your Note-Taking App with the Filesystem?

Using the filesystem instead of a database or cloud service for your note-taking app isn't just a simpler starting point—it's a masterclass in fundamental programming concepts that every developer needs to understand.

You're learning the foundation underneath everything

Every piece of software ultimately interacts with files. Databases? They store data in files. Web servers? They serve files. Cloud applications? They manage files across distributed systems. By working directly with the filesystem, you're learning the bedrock skills that power everything else.

Essential skills you'll develop:

File I/O operations - You'll master reading from and writing to files, which is core to virtually every application. Whether you're processing configuration files, importing data, or generating reports, these skills transfer everywhere.

Data serialization and parsing - Converting your note objects into text (JSON, Markdown, XML) and back again teaches you how data moves between memory and storage. This same concept applies when sending data over networks or saving user preferences.

Directory structure and organization - Deciding how to organize notes (by date? by topic? in nested folders?) teaches you about data modeling and hierarchical thinking. These concepts directly apply to database design, URL routing in web apps, and organizing any complex system.

Error handling and edge cases - What happens when a file is corrupted? When the disk is full? When two processes try to write the same file? Filesystem programming forces you to think about real-world failure scenarios.

Performance considerations - You'll discover why reading one large file might be faster than many small ones, or why scanning hundreds of files can be slow. These insights apply to database queries, API calls, and system optimization everywhere.

Practical examples from your note-taking app:

File naming and collision handling - When a user creates two notes with the same title, how do you handle it? Do you append timestamps? Create numbered versions? This teaches you about unique identifiers and conflict resolution.

Incremental loading - If you have thousands of notes, you can't load them all into memory. You'll learn to read file lists, load metadata first, and fetch full content on demand—the same patterns used in web pagination and lazy loading.

Search without databases - Building search functionality by scanning files teaches you about indexing, text processing, and performance trade-offs. Later, when you use a database, you'll understand what it's doing behind the scenes.

Backup and versioning - How do you prevent data loss? How do you track changes? You might implement simple versioning by copying files or creating timestamps, learning the concepts behind version control systems.

Cross-platform compatibility - Different operating systems handle file paths differently. Learning to work with / vs \ separators and absolute vs relative paths teaches you about portability and system-level programming.

The learning progression:

You'll start simple—just saving text to a file. Then you'll want better organization, so you'll create folders. Then you'll want metadata, so you'll learn JSON. Then you'll want search, so you'll read multiple files efficiently. Each step builds naturally on the last.

Why this beats starting with a database:

Databases hide complexity behind convenient APIs. While that's great for building applications quickly, it means you miss fundamental concepts about how data is actually stored and retrieved. When you eventually use databases (and you will), you'll understand the problems they're solving because you've faced those problems yourself.

Real-world relevance:

Many successful applications started as filesystem-based tools. Git manages millions of files efficiently. Static site generators like Jekyll process thousands of markdown files. Log analysis tools parse massive text files. Configuration management systems organize files across servers.

Skills that transfer everywhere:

The file handling patterns you learn will apply when you're processing CSV data, managing configuration files, building deployment scripts, or working with any system that stores and retrieves information. You're not just building a note-taking app—you're learning to think like a systems programmer.

Starting with the filesystem gives you a deep understanding of how computers actually work with data. It's messier and more complex than using a database, but that complexity teaches you invaluable problem-solving skills. Every challenge you solve—from handling concurrent access to organizing large amounts of data—prepares you for the real-world complexities you'll face as a professional developer.

Ahem, about that Test-Driven Development thingie

What is Test-Driven Development (TDD)?

Test-Driven Development is a programming approach where you write tests before writing the actual code. It follows a simple cycle called "Red-Green-Refactor":

  1. Red: Write a failing test that describes what you want your code to do
  2. Green: Write the minimal code needed to make that test pass
  3. Refactor: Clean up and improve the code while keeping tests passing

Think of it like writing a recipe backwards - you first describe what the finished dish should taste like, then figure out how to cook it.

Why beginners should embrace TDD:

Clarifies your thinking - Writing tests first forces you to think through exactly what your function should do before you get lost in implementation details. It's like sketching before painting.

Catches bugs early - Tests act as a safety net. When you change code later, your tests immediately tell you if you broke something that was previously working.

Improves code design - Code that's easy to test tends to be well-organized and modular. TDD naturally pushes you toward better architecture.

Builds confidence - You can refactor and improve your code fearlessly, knowing your tests will catch any mistakes.

Serves as documentation - Good tests show other developers (including future you) how your code is supposed to work.

Need to Make Sure - There are 3-4 test For Every Method!!! Lots o'tests, many, many tests. So Many Tests!!

How to do TDD:

These test examples are in JavaScript, so use them only as conceptual examples. You will write this app in either Java or Python, and use the standard filesystem (using text files as your data format) for your storage infrastructure. Someday soon, you may get the chance (or motivation) to store the notes in a database of some kind, but for now, text files.

Let's say you're building a function to validate note titles. Here's the TDD process:

Step 1 (Red): Write a failing test

test('should reject empty note titles', () => {
  expect(validateNoteTitle('')).toBe(false);
});

Step 2 (Green): Write minimal code to pass

function validateNoteTitle(title) {
  return title !== '';
}

Step 3 (Refactor): Improve while keeping tests green

function validateNoteTitle(title) {
  return typeof title === 'string' && title.trim().length > 0;
}

Then repeat: add more tests for edge cases, implement features incrementally. Start small, with a tiny core of functionality. And then build outwards, add capabilities (and TESTs Tests tests) as you go!

TDD in your note-taking CLI application:

Here are specific areas where TDD would be valuable:

Note creation and validation

  • Test that notes require titles
  • Test that notes can have optional tags
  • Test that duplicate titles are handled appropriately
  • Test that special characters in titles are escaped properly

Search functionality

  • Test searching by keywords finds correct notes
  • Test case-insensitive search works
  • Test searching with multiple tags
  • Test handling of search terms with special characters

File operations

  • Test that notes are saved to the correct file format
  • Test that corrupted files are handled gracefully
  • Test that backup creation works
  • Test that notes can be exported to different formats

Command parsing

  • Test that CLI commands are parsed correctly (add, search, delete)
  • Test that invalid commands show helpful error messages
  • Test that command flags work as expected (--tag, --date)

Example TDD workflow for your CLI app:

// Test first
test('should create note with title and content', () => {
  const note = createNote('My First Note', 'This is the content');
  expect(note.title).toBe('My First Note');
  expect(note.content).toBe('This is the content');
  expect(note.createdAt).toBeInstanceOf(Date);
});

// Then implement
function createNote(title, content) {
  return {
    title: title,
    content: content,
    createdAt: new Date(),
    id: generateId()
  };
}

Getting started:

  1. Choose a testing framework (junit for Java, pytest and/or unittest for Python, etc.)
  2. Start with simple, pure functions (like validation, method correctness or formatting)
  3. Write one test, make it pass, then add another
  4. Don't try to test everything at once - build up gradually

TDD might feel slow initially, but it pays huge dividends as your application grows. You'll spend less time debugging mysterious bugs and more time confidently adding new features. For a personal project like this note-taking app, it also helps you think through the user experience before getting caught up in implementation details.

Finally

Why does choosing to use text files in a standard directory structure using Markdown as a note format, make the project "future proof"?

Using text files in a standard directory structure with Markdown as a note format makes a project "future proof" for several compelling reasons:

Universal Compatibility

  • Plain text files (.txt, .md) are readable by virtually any operating system and text editor, eliminating dependency on proprietary software
  • UTF-8 encoding ensures support for multiple languages and special characters across all modern systems

Longevity and Stability

  • Text files have remained a stable format for decades and will likely be readable for decades to come
  • Unlike proprietary formats that can become obsolete when companies discontinue support

Version Control Friendly

  • Text files integrate seamlessly with version control systems like Git
  • Changes can be tracked line by line, enabling precise collaboration and history tracking

Portable and Accessible

  • Files can be easily transferred between devices and platforms
  • Low storage requirements compared to binary formats

Human Readable

  • Content remains accessible without specialized software
  • Even if the application becomes obsolete, notes remain directly readable

Open Standards

  • Markdown is an open specification with wide industry support
  • Not controlled by a single entity that could change or abandon the format

Flexibility and Extensibility

  • Directory structures can be organized according to user preference
  • Metadata in YAML headers can evolve over time without breaking backward compatibility
  • New features can be added without rendering old files unusable

Searchable

  • Plain text is easily searchable using standard system tools or simple scripts
  • No need for specialized databases that might become obsolete

Data Sovereignty

  • Users maintain complete control over their data
  • No dependence on cloud services that may change terms or shut down

Resilient Against Software Evolution

  • Even as the application evolves through its three phases (CLI → GUI → web), the underlying data format remains consistent
  • Allows for migration to newer systems without data loss

This approach creates a foundation that can withstand technological change, ensuring that notes remain accessible regardless of future software and hardware developments.

About

a text-based file notes app

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published