# Project Notes

A lightweight, web-based Markdown note-taking application with a Go backend and a minimalist frontend built with htmx. It allows users to create, edit, delete, and search Markdown notes, with automatic front matter management and a live Markdown preview.

## Features

*   **File-based Notes:** All notes are stored as plain Markdown files (`.md`) on the filesystem.
*   **Tag Indexing:** Notes are indexed by tags specified in their YAML front matter, enabling quick search.
*   **CodeMirror 6 Editor:** Modern, powerful Markdown editor with syntax highlighting and One Dark theme.
*   **Live Markdown Preview:** Side-by-side editor and live preview pane with scroll synchronization.
*   **Automatic Front Matter:** Automatically generates and updates `title`, `date` (creation), `last_modified`, and `tags` in YAML front matter.
*   **Slash Commands:** Insert common Markdown elements and dynamic content (like current date) using `/` commands in the editor.
*   **Search Modal:** Press `Ctrl/Cmd+K` to open a powerful search modal with keyboard navigation and real-time results.
*   **Dynamic File Tree:** Automatically updating file tree in the sidebar to navigate notes.
*   **Hierarchical Organization:** Organize notes in folders with drag-and-drop file management.
*   **Rich Search:** Search by keywords, tags (`tag:projet`), title (`title:meeting`), or path (`path:backend`).
*   **REST API:** Full REST API (`/api/v1/notes`) for programmatic access - list, read, create, update, and delete notes via HTTP.
*   **Lightweight Frontend:** Built with htmx for dynamic interactions, minimizing JavaScript complexity.
*   **Go Backend:** Fast and efficient Go server handles file operations, indexing, and serving the frontend.

## Technologies Used

*   **Backend:** Go
    *   `net/http`: Standard library for the web server.
    *   `github.com/fsnotify/fsnotify`: For watching file system changes and re-indexing.
    *   `gopkg.in/yaml.v3`: For parsing and marshaling YAML front matter.
*   **Frontend:** HTML, CSS, JavaScript
    *   [htmx](https://htmx.org/): For dynamic UI interactions without writing much JavaScript.
    *   [CodeMirror 6](https://codemirror.net/6/): For the robust Markdown editor.
    *   [marked.js](https://marked.js.org/): For client-side Markdown parsing in the preview.
    *   [DOMPurify](https://dompurpurify.com/): For sanitizing HTML output from Markdown to prevent XSS vulnerabilities.
    *   [Highlight.js](https://highlightjs.org/): For syntax highlighting in code blocks.
    *   Custom CSS theme with dark mode inspired by VS Code and GitHub Dark.

## Getting Started

### Prerequisites

*   [Go](https://go.dev/doc/install) (version 1.22 or higher recommended)

### Installation

1.  **Clone the repository:**
    ```bash
    git clone https://github.com/mathieu/project-notes.git
    cd project-notes
    ```
2.  **Download Go modules:**
    ```bash
    go mod tidy
    ```

### Frontend Build Process

**IMPORTANT**: The frontend must be built before running the application.

The frontend uses [Vite](https://vitejs.dev/) to bundle CodeMirror 6 and other JavaScript modules. This step is **required** for the editor to work.

1.  **Install Node.js dependencies** (first time only):
    ```bash
    cd frontend
    npm install
    ```

2.  **Build the frontend**:
    ```bash
    npm run build
    ```

    This compiles `frontend/src/` files into `static/dist/` (served by Go).

3.  **Development mode** (auto-rebuild on changes):
    ```bash
    npm run build -- --watch
    ```

### Running the Application

1.  **Build the frontend** (see above, required!)

2.  **Start the Go backend server**:
    ```bash
    go run ./cmd/server
    ```

3.  **Access the application** at `http://localhost:8080`

**Production build**:
```bash
# Build frontend
cd frontend && npm run build && cd ..

# Compile Go binary
go build -o server ./cmd/server

# Run
./server
```

## Usage

### Creating a New Note

1.  Click the "✨ Nouvelle note" button in the header.
2.  Enter a filename (e.g., `my-new-note.md`) in the modal dialog.
3.  Click "Créer / Ouvrir" - if the note exists, it will be opened; otherwise, a new note will be created.
4.  An editor will appear with pre-filled YAML front matter (title, creation date, last modified date, and a "default" tag).

### Editing a Note

1.  Click on a note in the "Notes" file tree in the sidebar.
2.  The note's content will load into the editor.
3.  Make your changes in the left pane (textarea). The right pane will show a live preview.
4.  Click the "Enregistrer" button or use **Ctrl/Cmd+S** to save your changes. The `last_modified` date in the front matter will be updated automatically.

### Searching Notes

**Quick Search Modal** (Recommended):
1.  Press **`Ctrl/Cmd+K`** anywhere to open the search modal.
2.  Type your query - results appear instantly with keyboard navigation.
3.  Use **`↑`/`↓`** to navigate, **`Enter`** to open, **`Esc`** to close.

**Search Syntax** (works in both modal and header search):
1.  **General search:** Type keywords to search across title, tags, path, and content.
2.  **Tag filter:** Use `tag:projet` to filter by specific tags.
3.  **Title filter:** Use `title:meeting` to search within note titles.
4.  **Path filter:** Use `path:backend` to search by file path.
5.  **Quoted phrases:** Use `"exact phrase"` to search for exact matches.

Results are scored and ranked by relevance (title matches score highest).

### Using Slash Commands

1.  While editing a note, type `/` at the start of a line in the textarea.
2.  A command palette will appear with available commands.
3.  Type to filter commands (e.g., `/h1`, `/date`, `/table`).
4.  Use `ArrowUp`/`ArrowDown` to navigate and `Enter` or `Tab` to select a command.
5.  The corresponding Markdown snippet will be inserted at your cursor position.

**Available commands:** h1, h2, h3, list, date, link, bold, italic, code, codeblock, quote, hr, table

### Organizing Notes in Folders

1.  Click the "📁 Nouveau dossier" button in the sidebar.
2.  Enter a folder path (e.g., `projets` or `projets/backend`).
3.  The folder will be created and appear in the file tree.
4.  Drag and drop notes between folders to reorganize them.

### Deleting a Note

1.  Load the note you wish to delete into the editor.
2.  Click the "Supprimer" button.
3.  Confirm the deletion when prompted. The note will be removed from the filesystem and the file tree will update automatically.

## Server Configuration

The server accepts the following command-line flags:

- `-addr :PORT` - Change server address (default: `:8080`)
- `-notes-dir PATH` - Change notes directory (default: `./notes`)

Example:
```bash
go run ./cmd/server -addr :3000 -notes-dir ~/my-notes
```

## REST API

Project Notes includes a full REST API for programmatic access to your notes.

**Base URL**: `http://localhost:8080/api/v1`

### Quick Examples

**List all notes**:
```bash
curl http://localhost:8080/api/v1/notes
```

**Get a specific note** (JSON):
```bash
curl http://localhost:8080/api/v1/notes/projet/backend.md
```

**Get note as Markdown**:
```bash
curl http://localhost:8080/api/v1/notes/projet/backend.md \
  -H "Accept: text/markdown"
```

**Create/Update a note**:
```bash
curl -X PUT http://localhost:8080/api/v1/notes/test.md \
  -H "Content-Type: application/json" \
  -d '{
    "body": "\n# Test\n\nContent here...",
    "frontMatter": {
      "title": "Test Note",
      "tags": ["test"]
    }
  }'
```

**Delete a note**:
```bash
curl -X DELETE http://localhost:8080/api/v1/notes/old-note.md
```

### Full API Documentation

See **[API.md](./API.md)** for complete documentation including:
- All endpoints (LIST, GET, PUT, DELETE)
- Request/response formats
- Content negotiation (JSON/Markdown)
- Advanced examples (sync, backup, automation)
- Integration guides

### Use Cases

- **Backup**: Automate note backups with cron jobs
- **Sync**: Synchronize notes across machines
- **Integration**: Connect with other tools (Obsidian, Notion, etc.)
- **Automation**: Create notes programmatically (daily notes, templates)
- **CI/CD**: Validate Markdown in pipelines

**⚠️ Security Note**: The API currently has no authentication. Use a reverse proxy (nginx, Caddy) with auth if exposing publicly.
