From 79fd6fd6dba3b367ba2afb9e28e16859310110cf Mon Sep 17 00:00:00 2001 From: Derek Cooper Date: Fri, 3 Apr 2026 00:56:48 -0700 Subject: [PATCH] Updated preference files --- CLAUDE.md | 16 ++++++++++ preferences/articles.md | 11 +++++-- preferences/powershell-wpf.md | 6 ++++ preferences/project-structure.md | 23 +------------ preferences/python-web.md | 55 ++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0013343..1b25242 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,6 +34,9 @@ See [preferences/communication.md](preferences/communication.md) for full detail - **No credentials in code:** Secrets go in `.env` files; always provide a `.env.example` - **Consistent style:** Follow the conventions for the language in use — see preferences files - **Ask before big changes:** Clarify scope before rewriting or restructuring +- Ask clarifying questions before starting — outline the plan for large changes and get confirmation before proceeding +- When a request is ambiguous, offer 2–3 specific options rather than an open-ended question +- Report failures clearly (what broke, why) and propose an alternative — don't retry the same failing approach --- @@ -43,6 +46,19 @@ See [preferences/communication.md](preferences/communication.md) for full detail - Add features, refactoring, or cleanup beyond what was asked - Put credentials, passwords, or tokens directly in code or config files - Switch to a different stack/library without asking first +- Add filler phrases ("Great question!", "Certainly!", "Of course!") +- Restate what was just asked before answering +- Suggest improvements or refactors beyond what was asked +- Propose switching to a different stack or library without being asked + +--- + +## Git Workflow + +- Commit directly to `main` — no PR workflow for solo projects +- Commit messages: short imperative summary (`Add user auth`, `Fix config loading`) +- Never commit `.env` — always commit `.env.example` with placeholders +- `.gitignore` must be present and project-appropriate from the start --- diff --git a/preferences/articles.md b/preferences/articles.md index 201194c..e8dec34 100644 --- a/preferences/articles.md +++ b/preferences/articles.md @@ -2,7 +2,8 @@ ## File Location & Naming -- **Directory**: `/home/dockersa/chns.tech/content/posts/YYYY/` +- **New posts (staging)**: `CHNS.tech/staged-posts/` — write all new posts here first +- **Published location**: `/home/dockersa/chns.tech/content/posts/YYYY/` — only after review - **Filename format**: `MM-DD-{slug}.md` (e.g., `03-11-docker-setup-guide.md`) - **Slug**: lowercase, hyphen-separated, descriptive @@ -112,11 +113,15 @@ Search all existing posts in `/home/dockersa/chns.tech/content/posts/` and link Use `##` for primary sections. Avoid deep nesting. ### Code Blocks -Use plain fenced code blocks — do not specify a language: +Always specify the language: ````markdown -``` +```bash command here ``` + +```yaml +key: value +``` ```` ### Inline Code diff --git a/preferences/powershell-wpf.md b/preferences/powershell-wpf.md index 7c91f11..30c7380 100644 --- a/preferences/powershell-wpf.md +++ b/preferences/powershell-wpf.md @@ -104,6 +104,12 @@ Import-Module "$script:AppRoot\Modules\ProjectName.psm1" -Force - Do **not** create test files — I'll run the code directly to verify it works - If asked to write tests, use **Pester** with `Invoke-Pester -Path .\Tests\ -Output Detailed` +## Common Gotchas + +- **Variable followed by colon:** `"$var: text"` fails — PowerShell treats `: text` as part of the variable name. Use `"${var}: text"` instead. +- **Returning arrays from functions:** A single-item array gets unrolled on return. Use `return ,$array` (comma prefix) to force PowerShell to return the array as-is. +- **UTF-8 file writes:** Use `[System.IO.File]::WriteAllText($path, $content, [System.Text.Encoding]::UTF8)` instead of `Out-File` — avoids BOM and encoding issues with special characters. + ## Comments - Comment the **why**, not the **what** — code should be readable on its own diff --git a/preferences/project-structure.md b/preferences/project-structure.md index 0fac3bc..7d8524e 100644 --- a/preferences/project-structure.md +++ b/preferences/project-structure.md @@ -62,28 +62,7 @@ project-name/ ## Hugo Blog (chns.tech) -Static site for tech blog posts. - -``` -site/ -├── hugo.toml # Site config -├── content/ -│ └── posts/ -│ └── YYYY-MM-DD-post-title.md -├── themes/ -├── static/ -└── layouts/ -``` - -**Post front matter standard:** -```yaml ---- -title: "Post Title" -date: YYYY-MM-DD -draft: false -tags: ["tag1", "tag2"] ---- -``` +See `preferences/articles.md` for the canonical post template, front matter, and formatting conventions. --- diff --git a/preferences/python-web.md b/preferences/python-web.md index 640db9a..a59fa2c 100644 --- a/preferences/python-web.md +++ b/preferences/python-web.md @@ -135,6 +135,61 @@ services: condition: service_healthy ``` +## Ntfy Notifications + +- All web apps must integrate Ntfy push notifications for admin-relevant events +- Use a self-hosted Ntfy instance; URL and topic stored in `.env` — never hardcoded +- Send notifications via HTTP POST using `httpx` (async) — do not add a separate Ntfy library + +```python +# app/utils/notify.py +import httpx +from app.config import settings + +async def notify(title: str, message: str, priority: str = "default", tags: list[str] | None = None): + headers = { + "Title": title, + "Priority": priority, + } + if tags: + headers["Tags"] = ",".join(tags) + async with httpx.AsyncClient() as client: + await client.post( + f"{settings.ntfy_url}/{settings.ntfy_topic}", + content=message, + headers=headers, + ) +``` + +**Required `.env` variables:** +``` +NTFY_URL=https://ntfy.example.com +NTFY_TOPIC=your-topic +``` + +**Standard events to notify on** (adapt to what the app actually does): + +| Event | Priority | Tags | +|---|---|---| +| Successful admin login | high | `warning` | +| Failed admin login (threshold reached) | urgent | `rotating_light` | +| New user registration | default | `busts_in_silhouette` | +| User account deletion | default | `wastebasket` | +| Role/permission escalation | high | `shield` | +| Password reset requested | default | `key` | +| Rate limit triggered | default | `no_entry` | +| API key created or revoked | high | `key` | +| Service startup / crash recovery | default | `white_check_mark` / `x` | +| High error rate (5xx spike) | high | `rotating_light` | +| Large data export initiated | default | `outbox_tray` | + +**Rules:** +- Add Ntfy to every new web app from the start — it is checked during go-live review +- Only notify on events that are genuinely useful to an admin — don't spam low-value noise +- Failed notifications must not crash the app — wrap calls in `try/except` and log the error + +--- + ## Testing - Do **not** create test files — I'll run the code directly to verify it works