built out personal preferences for AI tools
This commit is contained in:
37
preferences/communication.md
Normal file
37
preferences/communication.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Communication Preferences
|
||||
|
||||
## Response Depth
|
||||
|
||||
- **Default level:** Brief summary — what the code/change does, key decisions made, nothing more
|
||||
- **Deep detail:** When I ask "explain this", "why does this work", or "walk me through it" — go full depth with context, reasoning, and examples
|
||||
- **Never assume** I want the full explanation unless I ask; don't pad responses
|
||||
|
||||
## Format Rules
|
||||
|
||||
- Always use **bullet points** and **structured output** (headers, tables, lists)
|
||||
- Avoid prose paragraphs unless explaining a concept I asked about
|
||||
- Use code blocks for all code, commands, and file paths
|
||||
- Keep section headers short and scannable
|
||||
|
||||
## Before Doing Work
|
||||
|
||||
- **Ask clarifying questions first** — it's better to pause and confirm than to do work that gets thrown away
|
||||
- If a request is ambiguous, state your interpretation and ask if it's correct before proceeding
|
||||
- If a task will touch many files or make large structural changes, outline the plan first and get confirmation
|
||||
|
||||
## When Something Is Unclear
|
||||
|
||||
- Say so directly — don't guess silently
|
||||
- Offer 2–3 specific options to choose from rather than an open-ended question when possible
|
||||
|
||||
## Errors and Blockers
|
||||
|
||||
- Report errors clearly: what failed, why (if known), and what the options are
|
||||
- Don't retry the same failing approach repeatedly — propose an alternative
|
||||
|
||||
## Things to Avoid
|
||||
|
||||
- Filler phrases ("Great question!", "Certainly!", "Of course!")
|
||||
- Restating what I just said before answering
|
||||
- Explaining things I didn't ask about
|
||||
- Suggesting improvements or refactors beyond the scope of what was asked
|
||||
121
preferences/powershell-wpf.md
Normal file
121
preferences/powershell-wpf.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# PowerShell & WPF Standards
|
||||
|
||||
## General Rules
|
||||
|
||||
- Always include `#Requires -Version 5.1` at the top of every `.ps1` file
|
||||
- Use `$script:` scope for module-level variables — never `$Global:` unless absolutely necessary
|
||||
- Keep credential and sensitive values out of code — load from config files or environment variables only
|
||||
- Use `.psd1` files for all external configuration (not JSON, not XML, not hardcoded)
|
||||
|
||||
## Code Structure
|
||||
|
||||
- Organize code using `#region` / `#endregion` blocks with descriptive names
|
||||
- Group related functions within their own region
|
||||
- One function per logical task — keep functions focused
|
||||
|
||||
```powershell
|
||||
#region Configuration Functions
|
||||
|
||||
function Initialize-Config {
|
||||
...
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI Functions
|
||||
|
||||
function Show-MainWindow {
|
||||
...
|
||||
}
|
||||
|
||||
#endregion
|
||||
```
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- **Functions:** PascalCase Verb-Noun (`Get-UserConfig`, `Show-MainWindow`, `Initialize-App`)
|
||||
- **Variables:** PascalCase (`$UserConfig`, `$ScriptRoot`, `$AppVersion`)
|
||||
- **Script-scoped:** `$script:VariableName`
|
||||
- Use approved PowerShell verbs (`Get-`, `Set-`, `Show-`, `New-`, `Remove-`, `Initialize-`, `Invoke-`, etc.)
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Use `try/catch` for all operations that can fail (file I/O, network, registry, etc.)
|
||||
- Use `Write-Warning` for non-fatal errors that should be logged but allow execution to continue
|
||||
- Use `Write-Error` for failures that should stop the current operation
|
||||
- Create centralized helper functions for user-facing messages:
|
||||
|
||||
```powershell
|
||||
function Show-Error { param([string]$Message, [string]$Title = "Error") ... }
|
||||
function Show-Warning { param([string]$Message, [string]$Title = "Warning") ... }
|
||||
function Show-Info { param([string]$Message, [string]$Title = "Information") ... }
|
||||
```
|
||||
|
||||
## WPF Specifics
|
||||
|
||||
- Always ensure STA thread mode for WPF — include an STA re-launch block at the top of `.ps1` entry points
|
||||
- Load all WPF assemblies at the top of the file:
|
||||
|
||||
```powershell
|
||||
Add-Type -AssemblyName PresentationFramework
|
||||
Add-Type -AssemblyName PresentationCore
|
||||
Add-Type -AssemblyName WindowsBase
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
```
|
||||
|
||||
- Define XAML as a here-string and load it via `[System.Windows.Markup.XamlReader]::Parse()`
|
||||
- Use `$script:` variables to hold window/control references so they're accessible across functions
|
||||
|
||||
## Modules
|
||||
|
||||
- Shared/reusable functions belong in a `.psm1` module under a `Modules/` folder
|
||||
- The main `.ps1` entry point imports the module at startup:
|
||||
|
||||
```powershell
|
||||
Import-Module "$script:AppRoot\Modules\ProjectName.psm1" -Force
|
||||
```
|
||||
|
||||
- Module files follow the same naming, scoping, and region conventions
|
||||
|
||||
## Configuration Files
|
||||
|
||||
- Use `.psd1` (PowerShell Data Files) for all config — they're native, typed, and easy to version
|
||||
- Always provide a default config creation block if the file doesn't exist
|
||||
- Config keys should use PascalCase nested hashtables:
|
||||
|
||||
```powershell
|
||||
@{
|
||||
Application = @{
|
||||
WindowWidth = 800
|
||||
WindowHeight = 600
|
||||
}
|
||||
Email = @{
|
||||
SMTPServer = ''
|
||||
From = ''
|
||||
To = ''
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Never put actual credentials in `.psd1` config — use placeholder strings with comments
|
||||
|
||||
## Testing
|
||||
|
||||
- Use **Pester** for unit testing
|
||||
- Always provide a Pester test file alongside new functions
|
||||
- At minimum, test: happy path, expected failure cases, and edge cases
|
||||
- Run tests with: `Invoke-Pester -Path .\Tests\ -Output Detailed`
|
||||
|
||||
```powershell
|
||||
# Tests/Get-UserConfig.Tests.ps1
|
||||
Describe "Get-UserConfig" {
|
||||
It "Returns default config when file does not exist" { ... }
|
||||
It "Loads config from valid .psd1 file" { ... }
|
||||
}
|
||||
```
|
||||
|
||||
## Comments
|
||||
|
||||
- Comment the **why**, not the **what** — code should be readable on its own
|
||||
- Use inline comments for non-obvious logic
|
||||
- Use block comments (`<# ... #>`) for function documentation (`.SYNOPSIS`, `.DESCRIPTION`, `.PARAMETER`, `.EXAMPLE`)
|
||||
116
preferences/project-structure.md
Normal file
116
preferences/project-structure.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Standard Project Structures
|
||||
|
||||
## PowerShell / WPF Application
|
||||
|
||||
For IT tooling and local GUI applications.
|
||||
|
||||
```
|
||||
ProjectName/
|
||||
├── ProjectName.ps1 # Main entry point — UI, startup, STA check
|
||||
├── company-settings.psd1 # External config — no credentials
|
||||
├── README.md
|
||||
├── Modules/
|
||||
│ └── ProjectName.psm1 # Shared functions, config loading, helpers
|
||||
├── Tests/
|
||||
│ └── *.Tests.ps1 # Pester test files
|
||||
└── Release-Notes/
|
||||
├── v1.0.md
|
||||
└── v1.1.md
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- Entry `.ps1` handles: STA check, assembly loading, module import, config load, show window
|
||||
- All reusable logic lives in the `.psm1` module, not inline in the entry point
|
||||
- Config file is always in the same directory as the script
|
||||
- `Release-Notes/` uses one file per version: `v{major}.{minor}.md`
|
||||
|
||||
---
|
||||
|
||||
## FastAPI Web Application (Docker Compose)
|
||||
|
||||
For self-hosted web apps running behind Nginx.
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── docker-compose.yml
|
||||
├── .env.example # Always committed — placeholder values only
|
||||
├── .gitignore # Must include .env
|
||||
├── README.md
|
||||
├── nginx/
|
||||
│ └── default.conf
|
||||
└── backend/
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
└── app/
|
||||
├── main.py
|
||||
├── config.py
|
||||
├── database.py
|
||||
├── dependencies.py
|
||||
├── models/
|
||||
│ └── user.py
|
||||
├── schemas/
|
||||
│ └── user.py
|
||||
├── routers/
|
||||
│ ├── auth.py
|
||||
│ └── [resource].py
|
||||
├── utils/
|
||||
└── tests/
|
||||
└── test_[resource].py
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- `.env` is never committed — `.env.example` always is
|
||||
- Each resource (users, items, etc.) gets its own model, schema, and router file
|
||||
- Tests live inside `backend/app/tests/`
|
||||
|
||||
---
|
||||
|
||||
## 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"]
|
||||
---
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Git Conventions
|
||||
|
||||
- **Branch:** Commit directly to `main` (solo projects)
|
||||
- **Commit messages:** Short imperative summary — `Add user auth`, `Fix config loading`, `Update README`
|
||||
- **Never commit:** `.env`, credentials, compiled binaries, `node_modules`, `__pycache__`
|
||||
- **Always include** a `.gitignore` appropriate for the project type
|
||||
|
||||
### Standard `.gitignore` entries
|
||||
|
||||
**PowerShell projects:**
|
||||
```
|
||||
*.exe
|
||||
company-settings.psd1 # If it contains org-specific paths
|
||||
```
|
||||
|
||||
**Python projects:**
|
||||
```
|
||||
.env
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.pytest_cache/
|
||||
```
|
||||
148
preferences/python-web.md
Normal file
148
preferences/python-web.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Python Web Stack Standards
|
||||
|
||||
## Stack
|
||||
|
||||
- **API:** FastAPI (async)
|
||||
- **ORM:** async SQLAlchemy 2.0 with ORM models (not raw queries)
|
||||
- **Database:** MySQL 8
|
||||
- **Runtime:** Docker Compose
|
||||
- **Reverse proxy:** Nginx
|
||||
- **Container management:** Portainer
|
||||
|
||||
## Project Layout
|
||||
|
||||
```
|
||||
project-name/
|
||||
├── docker-compose.yml
|
||||
├── .env.example # Template — always include this, never commit .env
|
||||
├── .gitignore
|
||||
├── README.md
|
||||
├── nginx/
|
||||
│ └── default.conf
|
||||
└── backend/
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
└── app/
|
||||
├── main.py # App entry point, router registration, startup events
|
||||
├── config.py # Settings loaded from environment via pydantic-settings
|
||||
├── database.py # Async SQLAlchemy engine and session factory
|
||||
├── dependencies.py # Shared FastAPI dependencies (auth, db session, etc.)
|
||||
├── models/ # SQLAlchemy ORM table definitions
|
||||
├── schemas/ # Pydantic request/response models
|
||||
├── routers/ # API endpoint handlers, one file per resource
|
||||
└── utils/ # Shared helpers
|
||||
```
|
||||
|
||||
## Configuration & Secrets
|
||||
|
||||
- All secrets and environment-specific values go in `.env` — never hardcode them
|
||||
- Always provide `.env.example` with placeholder values and comments explaining each variable
|
||||
- Load settings via `pydantic-settings`:
|
||||
|
||||
```python
|
||||
# app/config.py
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
class Settings(BaseSettings):
|
||||
db_host: str
|
||||
db_port: int = 3306
|
||||
db_name: str
|
||||
db_user: str
|
||||
db_password: str
|
||||
secret_key: str
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
|
||||
settings = Settings()
|
||||
```
|
||||
|
||||
## Database (SQLAlchemy 2.0 Async)
|
||||
|
||||
- Use async engine and session factory
|
||||
- Define models with `DeclarativeBase`
|
||||
- One model per file in `models/`
|
||||
|
||||
```python
|
||||
# app/database.py
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
pass
|
||||
```
|
||||
|
||||
- Inject DB sessions via FastAPI dependencies (not global sessions)
|
||||
- Use `async with session.begin()` for transactions
|
||||
|
||||
## Models
|
||||
|
||||
- One file per table in `models/`
|
||||
- Use typed columns with SQLAlchemy 2.0 `Mapped` syntax:
|
||||
|
||||
```python
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from app.database import Base
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
username: Mapped[str] = mapped_column(unique=True)
|
||||
email: Mapped[str]
|
||||
```
|
||||
|
||||
## Schemas (Pydantic)
|
||||
|
||||
- Separate schemas for Create, Update, and Response — don't reuse the same schema for all three
|
||||
- Response schemas should never expose password hashes or internal fields
|
||||
|
||||
```python
|
||||
class UserCreate(BaseModel): ...
|
||||
class UserResponse(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
```
|
||||
|
||||
## Routers
|
||||
|
||||
- One router file per resource (e.g., `routers/users.py`, `routers/auth.py`)
|
||||
- Register all routers in `main.py` with a consistent prefix and tags
|
||||
|
||||
## Docker Compose
|
||||
|
||||
- Use named volumes for persistent data (database, uploads)
|
||||
- Always define a `healthcheck` for the database service
|
||||
- Use `depends_on` with `condition: service_healthy` for the backend
|
||||
- Keep the Nginx config in a `nginx/` folder and mount it as a volume
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
image: mysql:8
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
- Use **pytest** with **pytest-asyncio** for async tests
|
||||
- Always provide a test for each router endpoint at minimum (happy path + 1 failure case)
|
||||
- Use a separate test database — never run tests against the real DB
|
||||
- Run with: `pytest -v`
|
||||
|
||||
## Comments
|
||||
|
||||
- Docstrings on all functions that aren't self-explanatory
|
||||
- Comment the **why** for non-obvious logic, not the what
|
||||
Reference in New Issue
Block a user