Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add comprehensive GitHub Copilot instructions for WeAllCode Django development workflow by Copilot · Pull Request #1520 · WeAllCode/website · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
# WeAllCode Website - Django Application

**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.**

WeAllCode is a Django web application for a nonprofit coding education organization that provides free educational resources and hands-on classes for children aged 7-17. The application manages class scheduling, user authentication, donations, and organizational content.

## Working Effectively

### Environment Setup & Build Process
**IMPORTANT**: Follow these exact steps to set up a working development environment:

1. **Copy environment configuration**:
```bash
cp .env.sample .env
```

2. **Generate SECRET_KEY**:
```bash
python -c "import secrets; print(secrets.token_urlsafe())"
```
Then update `.env` file with: `SECRET_KEY="<generated-key>"`

3. **Install uv package manager**:
```bash
pip install uv
```

4. **Install Python 3.11 (required version)**:
```bash
uv python install 3.11
```

5. **Install dependencies** - takes ~2.5 minutes. NEVER CANCEL:
```bash
uv sync
```
Set timeout to 5+ minutes.

6. **Setup PostgreSQL database**:
```bash
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo -u postgres createdb weallcode_local
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"
```

7. **Update .env for local database**:
```
DB_HOST=localhost
DB_NAME=weallcode_local
DB_USER=postgres
DB_PASSWORD=postgres
```

8. **Create environment setup script** (required due to compatibility issues):
```bash
cat > setup_env.sh << 'EOF'
#!/bin/bash
set -a
source .env
set +a
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}
source .venv/bin/activate
exec "$@"
EOF
chmod +x setup_env.sh
```

9. **Verify Django setup**:
```bash
./setup_env.sh python manage.py check
```

10. **Run database migrations** - takes ~4 seconds:
```bash
./setup_env.sh python manage.py migrate
```

11. **Load development fixtures** - takes ~1.5 seconds:
```bash
./setup_env.sh python manage.py loaddata fixtures/*.json
```

### Docker Setup (Alternative - Has SSL Issues)
**WARNING**: Docker build currently fails due to SSL certificate issues with PyPI in sandboxed environments.

```bash
# This fails due to SSL issues - documented for future reference
docker compose up --build # FAILS: SSL certificate verification
```

Use the local Python setup above instead.

## Running the Application

### Development Server
```bash
./setup_env.sh python manage.py runserver 0.0.0.0:8000
```
- Access at: http://localhost:8000
- **ALWAYS** use the `setup_env.sh` wrapper script - direct Django commands will fail due to missing environment variables

### Production-like Server (using invoke tasks)
```bash
./setup_env.sh invoke start # Uses gunicorn
```

### Common Invoke Tasks
```bash
./setup_env.sh invoke --list # List all available tasks
./setup_env.sh invoke migrate # Run migrations
./setup_env.sh invoke load-fixtures # Load fixtures
./setup_env.sh invoke collect-static # Collect static files
./setup_env.sh invoke release # Full release process (migrate + fixtures + static)
```

## Testing

### Unit Tests
**NOTE**: Unit tests currently have issues with debug toolbar and missing dependencies:
```bash
./setup_env.sh python manage.py test --debug-mode
# Known issues: debug toolbar conflicts, missing pytz dependency
```

### Linting - takes ~0.04 seconds:
```bash
./setup_env.sh ruff check . # Check for style issues
./setup_env.sh ruff check . --fix # Auto-fix issues
./setup_env.sh ruff format . # Format code
```

### Pre-commit Hooks
```bash
pip install pre-commit
pre-commit run --all-files
```

### End-to-End Tests (Cypress)
Located in `/test` directory with Node.js package:
```bash
cd test
npm install # Install Cypress dependencies
npm run test # Run headless tests
npm start # Open Cypress GUI
```
Requires Node.js 18.15.0+ as specified in test/package.json.

## Development Accounts

The application includes test accounts loaded via fixtures:

- **Admin**: `admin@sink.sendgrid.net` / `admin`
- **Mentor**: `mentor@sink.sendgrid.net` / `mentor`
- **Guardian**: `guardian@sink.sendgrid.net` / `guardian`

**NOTE**: These accounts may not work in development fixtures - create new accounts via the signup flow.

## Known Issues & Workarounds

### Storage Backend Compatibility
The application has a temporary fix for django-storages compatibility:
- `SpooledTemporaryFile` import is disabled in `coderdojochi/settings.py`
- This affects S3 storage in production but not local development

### Docker SSL Issues
Docker builds fail in sandboxed environments due to SSL certificate verification:
```
Error: certificate verify failed: self-signed certificate in certificate chain
```
Use local Python setup instead.

### Debug Toolbar
Causes test failures - configure `DEBUG_TOOLBAR_CONFIG['IS_RUNNING_TESTS'] = False` if needed.

## Validation

**ALWAYS** validate changes by:
1. Running `./setup_env.sh python manage.py check`
2. Starting the development server successfully
3. Accessing http://localhost:8000 and verifying the homepage loads
4. Running linting: `./setup_env.sh ruff check .`
5. Testing login functionality at `/account/login/`

## Key Project Structure

```
/
├── .env # Environment configuration (create from .env.sample)
├── manage.py # Django management script
├── setup_env.sh # Environment wrapper script (create this)
├── pyproject.toml # Python dependencies
├── tasks.py # Invoke task definitions
├── docker-compose.yml # Docker setup (has SSL issues)
├── coderdojochi/ # Main Django app
│ ├── settings.py # Django settings
│ ├── urls.py # URL routing
│ └── migrations/ # Database migrations
├── weallcode/ # Secondary Django app
├── accounts/ # User account management
├── fixtures/ # Development data
└── test/ # Cypress E2E tests
└── package.json # Node.js dependencies
```

## Always Use These Commands

**CRITICAL**: Always prefix Django commands with `./setup_env.sh` or they will fail:

✅ **CORRECT**:
```bash
./setup_env.sh python manage.py migrate
./setup_env.sh python manage.py runserver
./setup_env.sh invoke start
```

❌ **INCORRECT** (will fail):
```bash
python manage.py migrate # Missing environment variables
docker compose up --build # SSL certificate issues
```

## Time Expectations

Set appropriate timeouts for these operations:
- **uv sync**: ~2.5 minutes (set 5+ minute timeout)
- **Database migrations**: ~4 seconds
- **Loading fixtures**: ~1.5 seconds
- **Ruff linting**: ~0.04 seconds
- **Django server startup**: ~2 seconds
- **Django check**: ~1 second

**NEVER CANCEL** long-running operations like `uv sync` - they need time to complete.

Fixes #1519.
31 changes: 31 additions & 0 deletions setup_env.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Setup script for WeAllCode Django application

# Load environment variables from .env file
set -a
source .env
set +a

# Set any missing variables with placeholder values
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-PLACEHOLDER}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-PLACEHOLDER}
export AWS_STORAGE_BUCKET_NAME=${AWS_STORAGE_BUCKET_NAME:-PLACEHOLDER}
export SENDGRID_API_KEY=${SENDGRID_API_KEY:-PLACEHOLDER}
export DEFAULT_FROM_EMAIL=${DEFAULT_FROM_EMAIL:-hello+local@weallcode.org}
export CONTACT_EMAIL=${CONTACT_EMAIL:-hello+local@weallcode.org}
export SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL:-PLACEHOLDER}
export SLACK_ALERTS_CHANNEL=${SLACK_ALERTS_CHANNEL:-PLACEHOLDER}
export SENTRY_DSN=${SENTRY_DSN:-}
export RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY:-}
export RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY:-}
export META_SITE_PROTOCOL=${META_SITE_PROTOCOL:-http}
export META_SITE_DOMAIN=${META_SITE_DOMAIN:-localhost:8000}
export META_TWITTER_SITE=${META_TWITTER_SITE:-@weallcode}
export META_FB_APPID=${META_FB_APPID:-1454178301519376}
export DEFAULT_META_TITLE=${DEFAULT_META_TITLE:-We All Code}

# Activate virtual environment
source .venv/bin/activate

# Run the command passed as arguments
exec "$@"
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.