Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:46:40 +08:00
commit 66f1bf4fb0
33 changed files with 6059 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
# Apply shadcn Skill
Style existing React components/pages using shadcn/ui while respecting the projects custom Tailwind theme tokens.
## What This Skill Does
- Creates a todo list of target files to style (one task per component/page).
- Installs needed shadcn components (card, input, button, table, label, separator, navigation-menu, etc.).
- Pulls usage examples from the shadcn registry via MCP tools to match correct patterns/props.
- Replaces plain HTML with shadcn/ui components, keeping logic intact and using custom CSS variables (`--color-*`) from `src/index.css`.
- Verifies builds after styling changes.
## Prerequisites
- React + Vite project already set up with Tailwind and shadcn tokens (see `tailwind-setup` skill).
- Custom theme variables present in `frontend/src/index.css`.
- shadcn CLI available (`npx shadcn@latest`).
## Workflow (high level)
1) Make a todo list: one task per file that needs styling.
2) Install required shadcn components (`npx shadcn@latest add ...`) based on needs.
3) For each file: mark task in_progress → read file → fetch examples with MCP (`mcp__shadcn__get_item_examples_from_registries`) → apply shadcn components and theme vars → mark task completed.
4) Run `npm --prefix ./frontend run build` to ensure imports/JSX compile.
## Theme Integration Tips
- Use Tailwind arbitrary values with custom vars, e.g. `bg-[var(--color-primary-600)] hover:bg-[var(--color-primary-700)]`.
- Keep functionality and routing intact; only swap UI primitives.
- Add `data-testid` if tests rely on stable selectors.
## Outputs/Artifacts
- Styled components/pages using shadcn/ui.
- Todo list reflecting completed styling tasks.
- Successful build verification.
## Notes & Gotchas
- Always check component availability via MCP search before `shadcn add`.
- Maintain alias usage (`@/components`, `@/lib/utils`, etc.) consistent with project.
- If existing CSS is important, migrate classes onto shadcn components rather than dropping them.

View File

@@ -0,0 +1,114 @@
---
name: apply-shadcn
description: Apply shadcn/ui components to React pages and components. This skill should be used when styling specific pages or components with shadcn/ui in a React project that has custom theming. The user will specify which pages or components to style.
allowed-tools: Bash, Write, Edit, Read, Glob, Grep, TodoWrite, mcp__shadcn__get_project_registries, mcp__shadcn__search_items_in_registries, mcp__shadcn__view_items_in_registries, mcp__shadcn__get_item_examples_from_registries, mcp__shadcn__get_add_command_for_items, mcp__shadcn__get_audit_checklist
---
## Overview
This skill applies shadcn/ui components to React pages and components while integrating with the project's custom theme defined in `frontend/src/index.css`.
## When to Use This Skill
Use this skill when the user requests to:
- Style specific pages with shadcn/ui components
- Apply shadcn/ui to a list of components
- Add shadcn/ui styling to authentication pages, navigation, or other UI elements
The user will provide either:
- A list of page/component names to style (e.g., "Style Login.jsx, SignUp.jsx, and NavBar.jsx")
- A category of pages to style (e.g., "Style all authentication pages")
## Workflow
### Step 1: Create a Todo List
Create a todo list with one task per page or component that needs styling. Each task should be named after the file being styled (e.g., "Style Login.jsx", "Style NavBar.jsx").
### Step 2: Install Required shadcn Components
Before styling any pages, ensure the necessary shadcn components are installed. Common components needed:
```bash
npx shadcn@latest add card input button table label separator navigation-menu
```
Adjust the component list based on what the pages require.
### Step 3: Style Each Page or Component
For each page or component in the todo list, follow this process:
1. **Mark the task as in_progress** in the todo list
2. **Read the existing file** to understand its current structure and functionality
3. **Use the MCP tool to get component examples**: Call `mcp__shadcn__get_item_examples_from_registries` to retrieve usage examples for the shadcn components needed (e.g., Card, Input, Button, Table)
4. **Review the examples** to understand:
- Proper component structure and composition
- Correct props and patterns
- Layout best practices
5. **Apply shadcn styling with custom theme integration**:
- Replace existing HTML elements with shadcn components
- Integrate custom CSS variables from `frontend/src/index.css` for colors
- Maintain existing functionality and logic
- Follow the theme integration guidelines below
6. **Mark the task as completed** in the todo list
7. **Move to the next page or component**
### Step 4: Verify All Tasks Complete
After styling all pages, verify that every task in the todo list is marked as completed.
### Step 5: Verify Setup
Run `npm run build` to validate imports, dependencies, and syntax
## Theme Integration Guidelines
**CRITICAL:** The project uses custom CSS variables defined in `frontend/src/index.css`. When styling components that need custom colors, use these variables instead of shadcn's default theme classes.
### Custom CSS Variables
Available custom variables from `frontend/src/index.css`:
- `--color-primary-{50-950}` - Primary color scale
- `--color-secondary-{50-950}` - Secondary color scale
- `--color-accent-{50-950}` - Accent color scale
- `--color-success-{50-900}` - Success colors
- `--color-error-{50-900}` - Error colors
### Example: Styling Primary Buttons
Use custom CSS variables with Tailwind's arbitrary value syntax:
```jsx
<Button
className="w-full bg-[var(--color-primary-600)] hover:bg-[var(--color-primary-700)] text-white"
>
Button Text
</Button>
```
**Why use custom variables:** The custom theme uses specific color values (e.g., purple hue at 250) that differ from shadcn's default theme. Using `bg-[var(--color-primary-600)]` ensures styled pages match the rest of the application.
## Common shadcn Components Used
- `card` - Card, CardContent, CardDescription, CardHeader, CardTitle
- `input` - Input
- `button` - Button
- `table` - Table, TableBody, TableCell, TableHead, TableHeader, TableRow
- `navigation-menu` - Navigation menu components
- `label` - Label
- `separator` - Separator
## Notes
- Always use the MCP tool before editing to understand proper component usage
- Preserve existing component functionality and logic
- Integrate custom theme variables for consistent styling
- Work through the todo list systematically, one page at a time
- Mark each task as completed immediately after finishing it

View File

@@ -0,0 +1,63 @@
# Django Allauth (Headless) Skill
Headless authentication setup for Django backends that serve React/Vue/mobile frontends. Adds django-allauth with MFA, social login, CORS, and REST endpoints—no server-rendered auth pages.
## What This Skill Delivers
- Installs auth stack: `django-allauth[socialaccount,mfa]`, `djangorestframework`, `django-cors-headers`, `fido2`, `python3-openid`, `Pillow`, `pyyaml`, `python-dotenv`.
- Configures headless mode (`HEADLESS_ONLY = True`) with frontend redirect URLs for email verification, password reset, signup, and social errors.
- Enables MFA (TOTP + WebAuthn/passkeys + recovery codes) and Google OAuth example.
- Sets CORS/CSRF for a separate HTTPS frontend (`FRONTEND_URL`), uses session/JWT-friendly middleware ordering.
- Adds REST URL prefixes: `accounts/` (admin/backend) and `_allauth/` (headless API).
- Provides validation harness to run the official headless allauth tests (76 core cases) via `scripts/validate_allauth_tests.sh` and detailed coverage notes in `references/test-validation-guide.md`.
## Skill Contents
- `SKILL.md` — step-by-step build instructions (install deps → settings.py edits → .env → URLs → checks → migrations → tests).
- `scripts/validate_allauth_tests.sh` — helper to run core allauth tests after cloning `django-allauth`.
- `references/test-validation-guide.md` — explains test categories, required pytest versions, and troubleshooting.
## Prerequisites
- Existing Django project with virtualenv.
- `FRONTEND_URL` to point at your HTTPS SPA (e.g., `https://localhost:5173`).
## Setup Summary (see SKILL.md for exact edits)
1) **Install packages** (venv active):
```bash
pip install 'django-allauth[socialaccount,mfa]' python-dotenv djangorestframework django-cors-headers fido2 python3-openid Pillow pyyaml
```
2) **settings.py changes:**
- Load env vars: `from dotenv import load_dotenv; load_dotenv('.env.development')`.
- Add CORS/CSRF hosts: `FRONTEND_URL`, `ALLOWED_HOSTS`, `CORS_ALLOWED_ORIGINS`, `CSRF_TRUSTED_ORIGINS`.
- Ensure `django.template.context_processors.request` is in `TEMPLATES[0]['OPTIONS']['context_processors']`.
- `INSTALLED_APPS` add: `corsheaders`, `rest_framework`, `allauth`, `allauth.account`, `allauth.socialaccount`, `allauth.socialaccount.providers.google`, `allauth.mfa`, `allauth.headless`, `allauth.usersessions`.
- `MIDDLEWARE` order: keep `corsheaders.middleware.CorsMiddleware` after `SessionMiddleware`; add `allauth.account.middleware.AccountMiddleware` after `MessageMiddleware`.
- Auth backends + headless/MFA/social/email settings appended at file end (see SKILL.md block).
3) **Environment file** `.env.development` in project root:
```
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
```
4) **URLs** in project `urls.py`:
```python
path('accounts/', include('allauth.urls')),
path('_allauth/', include('allauth.headless.urls')),
```
5) **Sanity checks & DB**:
```bash
python manage.py check
python manage.py migrate
```
6) **Optional validation tests** (after cloning `django-allauth` sibling to project):
```bash
bash scripts/validate_allauth_tests.sh
```
## Outputs/Artifacts
- Headless auth APIs ready for SPA use.
- MFA-ready user flows (TOTP/WebAuthn/recovery codes).
- Dev email backend writes files to `sent_emails/` (adjust for production).
- Updated `requirements.txt` (after `pip freeze`).
## Notes & Gotchas
- Use pytest `<9.0` and `pytest-asyncio==0.23.8` for the provided test suite.
- Keep middleware order exact to avoid CORS/login issues.
- Set `MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True if DEBUG else False` so localhost HTTPS works during development.

View File

@@ -0,0 +1,372 @@
---
name: django-allauth
description: Configure django-allauth with headless API, MFA, social authentication, and CORS for React frontends. This skill should be used when setting up authentication for a new Django project or adding django-allauth to an existing project that needs a React frontend integration. (project)
---
## Overview
This skill configures django-allauth in headless mode for React/Vue/frontend applications. Unlike traditional Django authentication that renders server-side templates, headless mode exposes authentication as REST APIs, making it ideal for single-page applications (SPAs) and mobile apps.
**What this skill provides:**
- Complete django-allauth setup with headless API endpoints
- Multi-factor authentication (TOTP, WebAuthn, recovery codes)
- Social authentication (Google OAuth example included)
- CORS configuration for cross-origin frontend communication
- Email verification and password reset workflows
- Session management for authenticated users
**End result:** A Django backend with secure, production-ready authentication APIs that the React frontend can consume via HTTP requests.
## Prerequisites
Before using this skill, ensure:
- Django project is created
- Virtual environment is created
## Setup Steps
To set up django-allauth in headless mode for React, follow these steps:
1. Install Django-Allauth headless mode Dependencies
2. Configure `settings.py`
3. Create Environment File `.env.development`
4. Add URL routes to `urls.py`
5. Check Django Configuration
6. Run migrations
7. Validate Installation with Tests
---
### Step 1: Activate virtual environment and Install Django-Allauth headless mode Dependencies
Install the required packages for authentication, social login, MFA, and cross-origin requests:
```bash
source venv/bin/activate
pip install 'django-allauth[socialaccount,mfa]' python-dotenv djangorestframework django-cors-headers fido2 python3-openid Pillow pyyaml
```
**Package purposes:**
- `django-allauth[socialaccount,mfa]` - Core authentication with social providers and multi-factor auth
- `python-dotenv` - Load environment variables from `.env` files
- `djangorestframework` - REST API framework (required by allauth headless)
- `django-cors-headers` - Enable cross-origin requests from React frontend
- `fido2` - WebAuthn/passkey support for passwordless authentication
- `python3-openid` - OpenID authentication support for social providers
- `Pillow` - Image processing library (required for avatar/profile images)
- `pyyaml` - YAML parser (required for allauth configuration)
---
### Step 2: Configure `settings.py`
### Find the settings file using Glob tool with pattern "**/*settings.py"
**Editing steps for `settings.py`:**
- Add Environment Variable Loading
- Add FRONTEND_URL, ALLOWED_HOSTS, CORS_ALLOWED_ORIGINS AND CSRF_TRUSTED_ORIGINS
- Ensure 'django.template.context_processors.request' is included in the template context processors list
- Update INSTALLED_APPS
- Update MIDDLEWARE
- Add Django-Allauth Configuration settings to the end of the file
#### Add Environment Variable Loading
Insert these lines at the end of the existing imports (top of the file):
```python
import os
from dotenv import load_dotenv
load_dotenv('.env.development')
```
#### Ensure 'django.template.context_processors.request' is included in the template context processors list
**Why:** Django-allauth requires access to the request object in templates for authentication flows.
Find `TEMPLATES[0]['OPTIONS']['context_processors']` and check if this line exists in the list:
```python
'django.template.context_processors.request',
```
**If missing:** Add it to the end of the `context_processors` list
#### Update INSTALLED_APPS
Find the `INSTALLED_APPS` list and append the following to the end of the list:
```python
# Authentication and user management (django-allauth)
'allauth',
'allauth.account',
'allauth.socialaccount',
# Providers
'allauth.socialaccount.providers.google',
# Multi-Factor Authentication (MFA)
'allauth.mfa',
# Headless API support for allauth
'allauth.headless',
'allauth.usersessions',
```
The end result should look similar to:
```python
INSTALLED_APPS = [
# Django core apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Cross-Origin Resource Sharing
'corsheaders',
# REST API support
'rest_framework',
# Authentication and user management (django-allauth)
'allauth',
'allauth.account',
'allauth.socialaccount',
# Providers
'allauth.socialaccount.providers.google',
# Multi-Factor Authentication (MFA)
'allauth.mfa',
# Headless API support for allauth
'allauth.headless',
'allauth.usersessions',
]
```
#### Update MIDDLEWARE
Find the `MIDDLEWARE` list. After `'django.contrib.messages.middleware.MessageMiddleware',`, add:
```python
"allauth.account.middleware.AccountMiddleware",
```
**Critical middleware order requirements:**
- `CorsMiddleware` must come AFTER `SessionMiddleware` and BEFORE `CommonMiddleware` to properly handle CORS headers before request processing
- `AccountMiddleware` must come AFTER `MessageMiddleware` to access session-based authentication state
**Expected result:**
```python
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'allauth.account.middleware.AccountMiddleware', # ← Add here
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```
#### Add Django-Allauth Configuration settings to the end of the file
**Location:** At the very end of `settings.py`
**Action:** Append all of the following authentication and MFA configuration:
```python
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
# Account settings
ACCOUNT_EMAIL_VERIFICATION = "mandatory" # Require email verification before login
ACCOUNT_LOGIN_METHODS = {'email'} # Use email instead of username for login
ACCOUNT_SIGNUP_FIELDS = ['email*', 'password1*', 'password2*']
ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = False
ACCOUNT_LOGIN_BY_CODE_ENABLED = True # Enable passwordless login via email code
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
# Multi-Factor Authentication settings
MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"]
MFA_PASSKEY_LOGIN_ENABLED = True # Enable passwordless WebAuthn login
MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True if DEBUG else False # Allow localhost in dev
MFA_PASSKEY_SIGNUP_ENABLED = True
# Headless mode configuration
HEADLESS_ONLY = True # Disable server-side templates, use API endpoints only
HEADLESS_FRONTEND_URLS = {
"account_confirm_email": f"{FRONTEND_URL}/account/verify-email/{{key}}",
"account_reset_password": f"{FRONTEND_URL}/account/password/reset",
"account_reset_password_from_key": f"{FRONTEND_URL}/account/password/reset/key/{{key}}",
"account_signup": f"{FRONTEND_URL}/account/signup",
"socialaccount_login_error": f"{FRONTEND_URL}/account/provider/error",
}
# Provider specific settings
SOCIALACCOUNT_PROVIDERS = {
'google': {
'APP': {
'client_id': os.environ.get('GOOGLE_CLIENT_ID'),
'secret': os.environ.get('GOOGLE_CLIENT_SECRET'),
'key': ''
},
'FETCH_USERINFO': True,
}
}
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = BASE_DIR / 'sent_emails'
```
**Key configuration notes:**
- `HEADLESS_ONLY = True` disables Django's template-based authentication views and forces API-only mode
- `HEADLESS_FRONTEND_URLS` tells the backend where to redirect users in email links (e.g., password reset, email verification)
- Social providers can be added/removed from `SOCIALACCOUNT_PROVIDERS` as needed
- Email backend is set to console for development; change to SMTP for production
---
### Step 3: Create Environment File
**Location:** Project root (same directory as `manage.py`)
**File:** `.env.development`
**Action:** Create file with OAuth credentials (leave empty for now, fill in when setting up social auth):
```
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
```
**If file exists:** Only add missing keys, don't overwrite existing values
---
### Step 4: Add import and URL routes to `urls.py`
**Location:** Django project package (same directory as `settings.py`)
First add `include` to imports and then add allauth URLs in `urls.py`:
```python
path('accounts/', include('allauth.urls')), # Traditional allauth URLs (admin/backend)
path("_allauth/", include("allauth.headless.urls")), # Headless API endpoints for frontend
```
**Why two URL patterns:**
- `accounts/` - Django admin integration and backend management
- `_allauth/` - RESTful API endpoints that the React frontend will call
---
### Step 5: Check Django Configuration
Verify that all settings are correctly configured before running migrations:
```bash
python manage.py check
```
**Expected:** No errors (warnings about unapplied migrations are OK)
---
### Step 6: Run migrations
Create the database tables for authentication, social accounts, and MFA:
```bash
python manage.py migrate
```
**What this creates:**
- User authentication tables
- Social account provider tables
- MFA/WebAuthn tables
- Email verification tables
- Session management tables
---
### Step 7: Validate Installation with Tests
Verify the django-allauth installation by running the official test suite. This ensures all core functionality is working correctly.
#### Clone the django-allauth repository
If not already cloned, clone the official repository to access the test suite:
```bash
git clone https://github.com/pennersr/django-allauth.git
```
#### Install test dependencies
Install pytest and required testing packages:
```bash
pip install 'pytest>=7.4,<9.0' 'pytest-asyncio==0.23.8' pytest-django pytest-cov django-ninja
```
**Note:** Pytest 9.x has compatibility issues with the django-allauth test suite. Using pytest 8.x ensures all tests pass successfully.
#### Update requirements.txt
```bash
pip freeze > requirements.txt
```
#### Run the validation script
Use the validation script to run the core test suite at: `scripts/validate_allauth_tests.sh`
#### Expected test results
**Success criteria:** All 76 tests should pass
**Test coverage:**
- ✅ Login Tests (16 tests) - Basic login, failed attempts, rate limiting, input validation
- ✅ Signup Tests (12 tests) - User registration, email verification, password validation, enumeration prevention
- ✅ Logout Tests (4 tests) - GET and POST logout flows, session management
- ✅ Email Verification Tests (6 tests) - Mandatory/optional verification, cross-user security
- ✅ Password Reset Tests (8 tests) - Reset flow, email handling, rate limiting, invalid keys
- ✅ Password Change Tests (18 tests) - Password change and set workflows with various validation scenarios
- ✅ Session Tests (12 tests) - Session management, token handling, security edge cases
#### What the tests validate
These tests confirm that your installation properly supports:
- User authentication (login/logout)
- User registration with email verification
- Password reset and change workflows
- Security features (rate limiting, unicode protection)
- Multi-factor authentication infrastructure
- Session management
- Email handling
- Async middleware support
**If tests fail:** Review the error messages. Common issues include:
- Missing dependencies (install with pip)
- Database configuration errors
- Incorrect `settings.py` configuration
- Missing URL patterns
**For detailed test information:** See `references/test-validation-guide.md` for:
- Detailed breakdown of each test category
- What each test validates
- Running additional test suites (headless API, social auth, MFA)
- Troubleshooting common test failures
- Continuous validation strategies
### clean up the cloned repository
```bash
rm -rf django-allauth
```

View File

@@ -0,0 +1,268 @@
# Django-Allauth Test Validation Guide
This reference provides detailed information about the django-allauth test suite and what each test category validates.
## Core Headless API Test Suite
The core validation tests run **76 test cases** from the headless API test suite, ensuring comprehensive verification of the django-allauth installation for React/SPA applications.
**Important:** These are the **headless API** tests specifically designed for React/Vue/frontend integration, not the traditional Django template-based account tests.
## Test Requirements
- **Pytest version:** `>=7.4,<9.0` (pytest 9.x has compatibility issues)
- **Pytest-asyncio version:** `==0.23.8`
### Test Categories
#### 1. Login Tests (16 tests)
**File:** `tests/apps/headless/account/test_login.py`
**What's tested:**
- Password authentication (success and failure cases)
- Bad password handling
- User inactive account handling (with ACCOUNT_ALLOW_LOGIN_WITH_UNVERIFIED_EMAIL on/off)
- Login rate limiting to prevent brute force attacks
- Failed login rate limiting
- Already logged-in user scenarios
- Custom post-login response handling
- Input validation and error handling
**Key validations:**
- Users can successfully authenticate with valid credentials via API
- Invalid credentials return proper error responses (401)
- Rate limiting prevents brute force attacks
- Inactive users cannot log in
- Session tokens are properly created
- Headless API responses follow the correct format
#### 2. Signup Tests (12 tests)
**File:** `tests/apps/headless/account/test_signup.py`
**What's tested:**
- User registration via API with email and password
- Email verification during signup (mandatory/optional)
- Enumeration prevention (prevent revealing if email exists)
- Signup rate limiting
- Closed signup handling
- Signup while already logged in
- Passwordless signup flows (without password)
**Key validations:**
- New users can register successfully via API
- Email verification flows work correctly
- Security features prevent user enumeration
- Rate limiting prevents signup abuse
- Passwordless registration is supported
- Password policies are applied
- Security features prevent account enumeration
- Custom forms integrate properly
#### 3. Email Verification Tests (6 tests)
**File:** `tests/apps/headless/account/test_email_verification.py`
**What's tested:**
- Email verification with another user logged in (security test)
- Authentication with unverified email (mandatory vs optional)
- Bad/invalid verification key handling
**Key validations:**
- Email verification emails are sent via API
- Verification keys work correctly
- Mandatory verification prevents API login
- Security boundaries between users are maintained
- Invalid keys return proper error responses
#### 4. Password Reset Tests (8 tests)
**File:** `tests/apps/headless/account/test_reset_password.py`
**What's tested:**
- Complete password reset workflow via API
- Unknown user handling (enumeration prevention)
- Password reset rate limiting
- Password reset key rate limiting
- Wrong/invalid reset key handling (GET and POST)
**Key validations:**
- Users can reset forgotten passwords via API
- Reset tokens are secure and validated
- Rate limiting prevents abuse
- Unknown accounts don't leak information
- Invalid keys return proper error responses
#### 5. Password Change Tests (18 tests)
**File:** `tests/apps/headless/account/test_change_password.py`
**What's tested:**
- Password change for authenticated users via API
- Various validation scenarios (wrong current password, weak new password, etc.)
- Setting passwords for users without passwords
- Password change rate limiting
- Different password requirements (with/without current password)
**Key validations:**
- Authenticated users can change passwords via API
- All validation rules are enforced
- Current password verification works
- Users without passwords can set new ones
- Rate limiting prevents abuse
- API responses follow correct format
#### 6. Session/Logout Tests (4 tests)
**File:** `tests/apps/headless/account/test_session.py`
**What's tested:**
- Logout via API (app and browser modes)
- Session token handling
- Logout without valid token
- App session gone scenarios
**Key validations:**
- Sessions are properly terminated via API
- Authentication tokens are cleared
- Logout works in both app and browser modes
- Invalid logout attempts are handled gracefully
## Test Results Interpretation
### Expected Results
**All tests passing (76/76):**
```
======================== 76 passed, 6 warnings in 1.65s ========================
```
This confirms:
- ✅ Headless API installation is complete and correct
- ✅ All core authentication features are working
- ✅ Database migrations succeeded
- ✅ Settings are properly configured for headless mode
- ✅ Dependencies are installed
### Common Test Failures and Solutions
#### Pytest Version Issues
**Error:** `pytest.PytestRemovedIn9Warning` or test suite crashes
**Solution:** Downgrade pytest to version 8.x:
```bash
pip install 'pytest>=7.4,<9.0' 'pytest-asyncio==0.23.8'
```
**Reason:** Django-allauth test suite uses deprecated pytest features not compatible with pytest 9.x.
#### Missing Dependencies
**Error:** `ModuleNotFoundError: No module named 'openid'`
**Solution:** Install the missing packages:
```bash
pip install python3-openid Pillow pyyaml
```
Common missing packages:
- `python3-openid` - Required for OpenID provider support
- `Pillow` - Required for image handling tests
- `pyyaml` - Required for configuration tests
- `django-ninja` - Required for API integration tests
- `pytest-asyncio==0.23.8` - Required for async tests
#### Configuration Errors
**Error:** Tests fail with `ImproperlyConfigured`
**Solution:** Review `settings.py` for:
- Missing apps in `INSTALLED_APPS` (especially `allauth.headless`)
- Missing middleware in `MIDDLEWARE` (`allauth.account.middleware.AccountMiddleware`)
- Missing authentication backends
- Incorrect `HEADLESS_ONLY` or `HEADLESS_FRONTEND_URLS`
- Missing `FRONTEND_URL` setting
#### Database Issues
**Error:** `OperationalError` or migration errors
**Solution:**
```bash
python manage.py migrate
```
## Running Additional Headless API Tests
Beyond the core 76 validation tests, you can run additional headless API tests:
### All Headless Account Tests
Test all account-related API endpoints:
```bash
cd django-allauth
pytest tests/apps/headless/account/ -v
```
**Additional coverage:**
- Login by code (passwordless)
- Email verification by code
- Password reset by code
- Phone number authentication
- Reauthentication flows
- Change email workflows
### Headless Social Authentication Tests
Test OAuth provider integrations via API:
```bash
cd django-allauth
pytest tests/apps/headless/socialaccount/ -v
```
**Coverage:**
- Social account linking via API
- OAuth flows for SPAs
- Provider callbacks
- Token management
### Headless MFA Tests
Test multi-factor authentication via API:
```bash
cd django-allauth
pytest tests/apps/headless/mfa/ -v
```
**Coverage:**
- TOTP (Google Authenticator) setup and verification
- WebAuthn/Passkeys registration and authentication
- Recovery codes generation and usage
- Trusted device management
- MFA enforcement flows
### All Headless Tests
Run all headless API tests (150+ tests):
```bash
cd django-allauth
pytest tests/apps/headless/ -v
```
**Warning:** Full test suite takes several minutes to complete.
## Continuous Validation
After making configuration changes, re-run the validation tests to ensure everything still works:
```bash
bash scripts/validate_allauth_tests.sh
```
This is especially important after:
- Modifying `settings.py` (especially `HEADLESS_ONLY` and `HEADLESS_FRONTEND_URLS`)
- Adding new authentication backends
- Changing email verification settings
- Updating MFA configuration
- Installing new django-allauth versions
- Upgrading Django or Python versions
## Understanding Test Modes
The headless API tests run in two modes:
### App Mode
- Uses JWT tokens for authentication
- Suitable for mobile apps and SPAs
- Token-based session management
### Browser Mode
- Uses traditional cookies/sessions
- CSRF protection enabled
- Suitable for same-origin SPAs
Both modes are tested to ensure compatibility with different frontend architectures.

View File

@@ -0,0 +1,81 @@
#!/bin/bash
# Django-Allauth Installation Test Validator
# This script runs the official django-allauth test suite to verify installation
set -e # Exit on error
echo "======================================================================"
echo "Django-Allauth Installation Test Validator"
echo "======================================================================"
echo ""
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Activate virtual environment if it exists
if [ -d "venv/bin" ]; then
echo -e "${YELLOW}Activating virtual environment...${NC}"
source venv/bin/activate
echo -e "${GREEN}✓ Virtual environment activated${NC}"
elif [ -d "../venv/bin" ]; then
echo -e "${YELLOW}Activating virtual environment...${NC}"
source ../venv/bin/activate
echo -e "${GREEN}✓ Virtual environment activated${NC}"
else
echo -e "${YELLOW}⚠ No virtual environment found. Using system Python.${NC}"
fi
# Check if we're in the django-allauth directory
if [ ! -d "django-allauth/tests" ]; then
echo -e "${RED}Error: django-allauth tests not found.${NC}"
echo "Please ensure you've cloned the django-allauth repository:"
echo " git clone https://github.com/pennersr/django-allauth.git"
exit 1
fi
# Check if pytest is installed
if ! command -v pytest &> /dev/null; then
echo -e "${YELLOW}Installing test dependencies...${NC}"
pip install pytest pytest-django pytest-asyncio pytest-cov django-ninja
echo -e "${GREEN}✓ Test dependencies installed${NC}"
fi
# Change to django-allauth directory
cd django-allauth
echo "Running core django-allauth tests..."
echo "This will verify your installation is working correctly."
echo ""
# Run the core test suite
pytest \
tests/apps/account/test_login.py \
tests/apps/account/test_signup.py \
tests/apps/account/test_logout.py \
tests/apps/account/test_email_verification.py \
tests/apps/account/test_reset_password.py \
tests/apps/account/test_change_password.py \
tests/apps/account/test_security.py \
tests/apps/account/test_middleware.py \
tests/apps/account/test_models.py \
-v \
-W ignore::pytest.PytestRemovedIn9Warning \
--tb=short
# Capture exit code
EXIT_CODE=$?
echo ""
echo "======================================================================"
if [ $EXIT_CODE -eq 0 ]; then
echo -e "${GREEN}✓ All tests passed! Django-allauth is properly installed.${NC}"
else
echo -e "${YELLOW}⚠ Some tests failed, but this may be expected (e.g., async tests).${NC}"
echo "Check the output above for details."
fi
echo "======================================================================"
exit $EXIT_CODE

View File

@@ -0,0 +1,144 @@
# Django Setup Skill (HTTPS Development)
**For HTTPS-only Django projects using mkcert SSL certificates.**
## Skill Overview
This skill sets up Django projects specifically for **HTTPS local development**, which is required for:
- WebAuthn/Passkeys (MFA)
- Secure cookies
- Service workers
- Modern browser APIs
## Key Features
-**Automatic Python version selection** - Uses highest available 3.8-3.13, installs 3.13 if none found
-**HTTPS by default** - Integrated mkcert setup
-**Core dependencies** - Django, python-dotenv, djangorestframework, django-cors-headers; adds `uvicorn[standard]` for SSL serving
-**Uvicorn ASGI server** - With SSL support
-**Manual, guided setup** - No automation scripts, full control
## Progressive Disclosure Structure
```
django-setup/
├── SKILL.md # ⭐ Core skill (HTTPS-focused)
├── README.md # This file
├── platform-https/ # 🔒 mkcert + Uvicorn setup per OS
│ ├── mkcert-https-setup-macos.md
│ ├── mkcert-https-setup-linux.md
│ └── mkcert-https-setup-windows.md
├── platform-install/ # 📦 Platform-specific Python installation
│ ├── macos.md
│ ├── linux-ubuntu.md
│ ├── linux-fedora.md
│ └── windows.md
├── troubleshooting/ # 🔧 Problem-solving guides
│ ├── venv-issues.md
│ ├── pip-problems.md
│ └── django-errors.md
└── examples/ # 📋 Templates
└── .gitignore-template
```
## What's Different from Standard Django Setup?
| Standard Django | This Skill |
|----------------|------------|
| HTTP only (port 8000) | HTTPS with mkcert |
| `python manage.py runserver` | `./run.sh` / `run.bat` (Uvicorn with SSL) |
| No SSL certificates | SSL certs in `certs/` |
| Optional HTTPS | HTTPS required |
| Any dependencies | Focused: Django, dotenv, DRF, django-cors-headers + uvicorn |
## Quick Setup Flow
1. **Check/install Python 3.8-3.13** (uses highest, installs 3.13 if needed)
2. **Create venv** with selected Python version
3. **Install core dependencies** (Django, python-dotenv, djangorestframework, django-cors-headers)
4. **Create Django project** (`django-admin startproject backend .`)
5. **Set up mkcert HTTPS + Uvicorn** (platform-https guides install `uvicorn[standard]`, generate certs, create run script)
6. **Configure settings.py for CORS/CSRF** (adds corsheaders middleware & allowed origins)
7. **Add health + CSRF helper endpoints** (`api/health`, `api/csrf`)
8. **Run migrations** (`python manage.py migrate`)
9. **Optional VS Code launch config** (`.vscode/launch.json`)
10. **Test with HTTPS** (`./run.sh` or `run.bat``https://localhost:8000`)
## Why These Dependencies?
Authentication packages (allauth, etc.) are **intentionally excluded** and should be added later via the `django-allauth-config` skill to keep the base setup lean. `django-cors-headers` is included because the skill configures CORS/CSRF for a typical HTTPS frontend, and `uvicorn[standard]` is used to serve Django over SSL in development.
**Core dependencies:**
```bash
pip install Django python-dotenv djangorestframework django-cors-headers
```
**HTTPS server:**
```bash
pip install 'uvicorn[standard]'
```
**Add authentication later:**
```bash
# Use django-allauth-config skill
pip install django-allauth[socialaccount,mfa] django-cors-headers
```
## Integration with Other Skills
This skill integrates with:
- **mkcert-https-setup** - SSL certificate setup (referenced inline via platform-https guides)
- **django-allauth-config** - Add authentication after base setup
## Token Efficiency
**Core SKILL.md:** ~2,500 tokens (HTTPS-focused, no automation)
**Platform guides:** ~400-600 tokens (loaded only when needed)
**Troubleshooting:** ~300-500 tokens (loaded only on errors)
**Average context usage:** ~2,800 tokens
**Compared to v1.0 monolithic:** 65% reduction
## Usage
```bash
# User says: "Set up Django project for HTTPS"
# Claude loads: django-project-setup skill
# Guides through: Python → venv → Django → mkcert → test HTTPS
```
## Final Project Structure
```
project-root/
├── backend/ # Django project
├── backend/views.py # Health + CSRF token endpoints
├── certs/ # mkcert SSL certificates
│ ├── localhost+2.pem
│ └── localhost+2-key.pem
├── venv/ # Virtual environment
├── .gitignore
├── db.sqlite3 # Database
├── manage.py
├── requirements.txt # Django, dotenv, DRF, cors-headers, uvicorn
├── run.sh # HTTPS server script (macOS/Linux)
├── run.bat # HTTPS server script (Windows)
└── .vscode/launch.json # Optional VS Code debug config
```
## Version History
- **v3.0.0** - HTTPS-only, mkcert integration, uvicorn server, CORS/CSRF defaults, minimal automation
- **v2.0.0** - Progressive disclosure with bundled content (deprecated)
- **v1.0.0** - Initial monolithic skill (deprecated)
## Security Notes
🔒 **Local development only** - mkcert certificates only work on your machine
🔐 **Never commit** - `certs/`, `*.pem`, `.env` must be in `.gitignore`
⚠️ **Production** - Use real SSL certificates (Let's Encrypt, etc.)

View File

@@ -0,0 +1,404 @@
---
name: django-setup
description: Initialize Django projects for HTTPS development with virtual environments and mkcert SSL certificates
---
## Overview
**This skill sets up Django for HTTPS development** with virtual environments and local SSL certificates.
# Artifacts Builder
To set up Django for HTTPS development with virtual environments and local SSL certificates, follow these steps:
1. Verify/Install Python
2. Create Virtual Environment
3. Install Django and Dependencies
4. Create Django Project
5. Set Up HTTPS
6. Configure settings.py
7. Create a health API
8. Add import and URL routes to urls.py
9. Apply Initial Migrations
10. Test HTTPS Server
11. Create .gitignore
## Step 1: Verify/Install Python
### Check for Python 3.8 - 3.13
**Check all available Python versions:**
Detect the operating system by running `uname -s 2>/dev/null || echo %OS% 2>/dev/null || ver`
Execute the platform-specific command based on the detected system.
```bash
# macOS/Linux
for v in 3.8 3.9 3.10 3.11 3.12 3.13; do
if command -v python$v >/dev/null 2>&1; then
echo "✅ Python $v found: $(python$v --version)"
else
echo "❌ Python $v not found"
fi
done
```
```bash
# Windows
$versions = 3.8, 3.9, 3.10, 3.11, 3.12, 3.13
foreach ($v in $versions) {
try {
$output = py -$v --version 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "✅ Python $v found: $output"
} else {
Write-Host "❌ Python $v not found"
}
} catch {
Write-Host "❌ Python $v not found"
}
}
```
**Strategy:**
- If you have **any** Python 3.8 - 3.13, use the **highest version**
- If no compatible Python found, install **Python 3.13**
### Install Python 3.13 (if needed)
**No compatible Python?** See platform-specific installation:
- macOS → [platform-install/macos.md](platform-install/macos.md)
- Ubuntu/Debian → [platform-install/linux-ubuntu.md](platform-install/linux-ubuntu.md)
- Fedora/RHEL → [platform-install/linux-fedora.md](platform-install/linux-fedora.md)
- Windows → [platform-install/windows.md](platform-install/windows.md)
**Verify installation:**
```bash
python3.13 --version # or python3.12, python3.11, etc.
which python3.13 # macOS/Linux
where python # Windows
```
---
## Step 2: Create Virtual Environment
**Create venv with your Python version:**
```bash
# Use highest available version
python3.13 -m venv venv # macOS/Linux
py -3.13 -m venv venv # Windows
# Or use default python3
python3 -m venv venv
```
**Verify creation:**
```bash
ls venv/bin/activate # macOS/Linux - should exist
dir venv\Scripts\activate # Windows - should exist
```
**Errors?** See [troubleshooting/venv-issues.md](troubleshooting/venv-issues.md)
---
## Step 3: Install Django and Dependencies
**Activate virtual environment and upgrade pip:**
```bash
# macOS/Linux
source venv/bin/activate
pip install --upgrade pip
# Windows (PowerShell)
venv\Scripts\Activate.ps1
pip install --upgrade pip
# Windows (CMD)
venv\Scripts\activate.bat
pip install --upgrade pip
```
**Install core dependencies:**
```bash
pip install Django python-dotenv djangorestframework
```
**What's installed:**
- **Django** - Web framework
- **python-dotenv** - Environment variable management (for secrets)
- **djangorestframework** - REST API toolkit (optional but recommended)
**Update requirements.txt:**
```bash
pip freeze > requirements.txt
```
**Installation issues?** See [troubleshooting/pip-problems.md](troubleshooting/pip-problems.md)
---
## Step 4: Create Django Project
**Create project in current directory (flat structure):**
```bash
django-admin startproject backend .
```
**Important:** The `.` creates the project in your current directory, not a subdirectory.
**Verify creation:**
```bash
ls manage.py # Should exist
ls backend/settings.py # Should exist
```
---
## Step 5: Set Up HTTPS with mkcert
### Detect Operating System
Detect the operating system if you have not done it yet by running:
```bash
uname -s 2>/dev/null || echo %OS% 2>/dev/null || ver
```
### Platform-Specific Instructions
Follow the instructions for your operating system:
- **macOS** → [platform-https/mkcert-https-setup-macos.md](platform-https/mkcert-https-setup-macos.md)
- **Ubuntu/Debian (Linux)** → [platform-https/mkcert-https-setup-linux.md](platform-https/mkcert-https-setup-linux.md)
- **Windows** → [platform-https/mkcert-https-setup-windows.md](platform-https/mkcert-https-setup-windows.md)
**What these guides cover:**
1. Installing mkcert
2. Installing local certificate authority
3. Creating SSL certificates directory
4. Installing Uvicorn (ASGI server with SSL support)
5. Updating requirements.txt
6. Creating platform-specific run script (run.sh or run.bat)
**Note:** Replace `backend` with your project name if different in the run scripts.
### Create VS Code launch configuration:**
For debugging in VS Code, create `.vscode/launch.json`:
```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Django HTTPS (Uvicorn)",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"backend.asgi:application",
"--host", "0.0.0.0",
"--port", "8000",
"--ssl-keyfile", "./certs/localhost+2-key.pem",
"--ssl-certfile", "./certs/localhost+2.pem",
"--reload"
],
"django": true,
"justMyCode": true,
"python": "${workspaceFolder}/venv/bin/python"
}
]
}
```
---
## Step 6: Configure `settings.py`
### Find the settings file using Glob tool with pattern "**/*settings.py"
**Editing steps for `settings.py`:**
- Add FRONTEND_URL, ALLOWED_HOSTS, CORS_ALLOWED_ORIGINS AND CSRF_TRUSTED_ORIGINS
- Update INSTALLED_APPS
- Update MIDDLEWARE
### Add FRONTEND_URL, ALLOWED_HOSTS, CORS_ALLOWED_ORIGINS AND CSRF_TRUSTED_ORIGINS
Find the line `ALLOWED_HOSTS = []` in settings.py and replace that single line with:
```python
FRONTEND_URL = 'https://localhost:5173'
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
FRONTEND_URL,
]
CSRF_TRUSTED_ORIGINS = [
FRONTEND_URL,
]
```
### Update INSTALLED_APPS
Find the `INSTALLED_APPS` list and append the following to the end of the list:
```python
# Cross-Origin Resource Sharing
'corsheaders',
# REST API support
'rest_framework',
```
### Update MIDDLEWARE
Find the `MIDDLEWARE` list. After `'django.contrib.sessions.middleware.SessionMiddleware',`, add:
```python
'corsheaders.middleware.CorsMiddleware',
```
**Critical:**
- `CorsMiddleware` must come AFTER `SessionMiddleware` and BEFORE `CommonMiddleware`
**Expected result:**
```python
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', # ← Add here
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```
---
## Step 7: Create a health API
### Create backend/views.py (next to settings.py/urls.py):
```python
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.middleware.csrf import get_token
def api_health(request):
return JsonResponse({
"status": "ok",
"message": "Django is alive and speaking HTTPS",
})
@csrf_exempt
def csrf_token_view(request):
# This forces Django to generate/set the csrftoken cookie
token = get_token(request)
return JsonResponse({"csrftoken": token})
```
---
## Step 8: Add import and URL routes to `urls.py`
first add `from .views import api_health, csrf_token_view` to imports and then add these endpoints to `urls.py`:
```python
path('api/health/', api_health),
path('api/csrf/', csrf_token_view),
```
---
## Step 9: Apply Initial Migrations
**Run database migrations:**
```bash
python manage.py migrate
```
**Creates:**
- `db.sqlite3` database file
- Default tables for auth, admin, sessions
---
## Step 10: Test HTTPS Server
**Start the HTTPS server:**
**macOS/Linux:**
```bash
./run.sh
```
**Windows:**
```bat
run.bat
```
**Expected output:**
```
INFO: Started server process [12345]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on https://127.0.0.1:8000 (Press CTRL+C to quit)
```
**Open browser and visit:**
```
https://localhost:8000
```
**Expected:**
- ✅ Django welcome page (rocket ship)
- ✅ **No certificate warnings** (padlock icon shows secure)
- ✅ URL shows `https://` not `http://`
**If you see certificate warnings:** mkcert CA not properly installed. Run `mkcert -install` again and restart browser.
**Stop server:** Press `Ctrl+C`
**Issues?** See [mkcert-https-setup troubleshooting](../mkcert-https-setup/SKILL.md#common-issues--solutions)
---
## Step 11: Create .gitignore
**Strategy: Check for existing .gitignore first, then create or enhance accordingly.**
### Check if .gitignore already exists
**First, check if .gitignore exists in the project root:**
```bash
ls -la <path-to-root>/.gitignore
```
### Option A: No .gitignore exists
**If .gitignore does not exist, create it using the script at `scripts/create_gitignore.py`:**
```bash
# Create .gitignore in project root
python <path-to-this-skill>/django-setup/scripts/create_gitignore.py --output .
```
**Verify creation at project root:**
```bash
ls -la <path-to-root>/.gitignore # Should exist at project root
cat <path-to-root>/.gitignore # Review contents
```
### Option B: .gitignore already exists
**If .gitignore already exists, enhance it manually by reading both files and merging missing entries:**
1. **Read the existing .gitignore** to understand what's already covered
2. **Read the template** at `.claude/skills/django-setup/examples/.gitignore-template`
3. **Compare both files** to identify missing entries from the template
4. **Use the Edit tool** to append missing sections/entries to the existing .gitignore, preserving the existing content
5. **Avoid duplicates** - only add entries that don't already exist (case-insensitive comparison)
---

View File

@@ -0,0 +1,99 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Virtual Environment
venv/
env/
ENV/
.venv
# Django
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
/media
/staticfiles
# Environment Variables
.env
.env.local
.env.development
.env.production
.env.staging
*.env
# IDE / Editor
.vscode/
.idea/
*.swp
*.swo
*~
.project
.pydevproject
.settings/
# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
Desktop.ini
# SSL Certificates (if using mkcert)
certs/
*.pem
*.key
*.crt
*.cert
# Testing
.coverage
.coverage.*
htmlcov/
.tox/
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
# Jupyter Notebook
.ipynb_checkpoints
# Documentation builds
docs/_build/
site/
# PyCharm
.idea/
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@@ -0,0 +1,91 @@
## Step 5: Set Up HTTPS with mkcert (Ubuntu/Debian)
**1. Install mkcert (if not already installed):**
```bash
sudo apt install libnss3-tools
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64"
chmod +x mkcert-v*-linux-amd64
sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert
```
**2. Install local certificate authority:**
```bash
mkcert -install
```
**3. Create certificates directory:**
```bash
mkdir certs
mkcert -cert-file certs/localhost+2.pem -key-file certs/localhost+2-key.pem localhost 127.0.0.1 ::1
```
This creates:
• certs/localhost+2.pem (certificate)
• certs/localhost+2-key.pem (private key)
**4. Install Uvicorn (ASGI server with SSL support):**
Ensure you are at the project root and venv is activated:
```bash
pip install uvicorn[standard]
```
**5. Update requirements.txt:**
```bash
pip freeze > requirements.txt
```
**6. Create run.sh script (Linux):**
```bash
cat > run.sh << 'EOF'
#!/usr/bin/env bash
uvicorn backend.asgi:application \
--host 127.0.0.1 --port 8000 \
--ssl-keyfile ./certs/localhost+2-key.pem \
--ssl-certfile ./certs/localhost+2.pem
EOF
chmod +x run.sh
```
Note: Replace backend with your project name if different.
**7. Create VS Code launch configuration (optional):**
For debugging in VS Code, create `.vscode/launch.json`:
```bash
mkdir -p .vscode
cat > .vscode/launch.json << 'EOF'
{
"version": "0.2.0",
"configurations": [
{
"name": "Django HTTPS (Uvicorn)",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"backend.asgi:application",
"--host", "0.0.0.0",
"--port", "8000",
"--ssl-keyfile", "./certs/localhost+2-key.pem",
"--ssl-certfile", "./certs/localhost+2.pem",
"--reload"
],
"django": true,
"justMyCode": true,
"python": "${workspaceFolder}/venv/bin/python"
}
]
}
EOF
```
This allows you to:
- Run and debug Django with F5 in VS Code
- Set breakpoints in your Django code
- Automatic venv activation via the `python` path
Note: Replace `backend` with your project name if different.

View File

@@ -0,0 +1,50 @@
## Step 5: Set Up HTTPS with mkcert (macOS)
**1. Install mkcert (if not already installed):**
```bash
brew install mkcert
```
**2. Install local certificate authority:**
```bash
mkcert -install
```
**3. Create certificates directory:**
```bash
mkdir certs
mkcert -cert-file certs/localhost+2.pem -key-file certs/localhost+2-key.pem localhost 127.0.0.1 ::1
```
This creates:
• certs/localhost+2.pem (certificate)
• certs/localhost+2-key.pem (private key)
**4. Install Uvicorn (ASGI server with SSL support):**
Ensure you are at the project root and venv is activated:
```bash
pip install 'uvicorn[standard]'
```
**5. Update requirements.txt:**
```bash
pip freeze > requirements.txt
```
**6. Create run.sh script (macOS/Linux):**
```bash
cat > run.sh << 'EOF'
#!/usr/bin/env bash
uvicorn backend.asgi:application \
--host 127.0.0.1 --port 8000 \
--ssl-keyfile ./certs/localhost+2-key.pem \
--ssl-certfile ./certs/localhost+2.pem
EOF
chmod +x run.sh
```
Note: Replace backend with your project name if different.

View File

@@ -0,0 +1,83 @@
## Step 5: Set Up HTTPS with mkcert (Windows)
**1. Install mkcert (if not already installed):**
```powershell
choco install mkcert
```
**2. Install local certificate authority:**
```powershell
mkcert -install
```
**3. Create certificates directory:**
```powershell
mkdir certs
mkcert -cert-file certs/localhost+2.pem -key-file certs/localhost+2-key.pem localhost 127.0.0.1 ::1
```
This creates:
• certs/localhost+2.pem (certificate)
• certs/localhost+2-key.pem (private key)
**4. Install Uvicorn (ASGI server with SSL support):**
Ensure you are at the project root and venv is activated:
```powershell
pip install uvicorn[standard]
```
**5. Update requirements.txt:**
```powershell
pip freeze > requirements.txt
```
**6. Create run.bat script (Windows):**
```batch
@echo off
uvicorn backend.asgi:application ^
--host 127.0.0.1 --port 8000 ^
--ssl-keyfile ./certs/localhost+2-key.pem ^
--ssl-certfile ./certs/localhost+2.pem
```
Note: Replace backend with your project name if different.
**7. Create VS Code launch configuration (optional):**
For debugging in VS Code, create `.vscode/launch.json`:
```powershell
mkdir .vscode -Force
@"
{
"version": "0.2.0",
"configurations": [
{
"name": "Django HTTPS (Uvicorn)",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"backend.asgi:application",
"--host", "0.0.0.0",
"--port", "8000",
"--ssl-keyfile", "./certs/localhost+2-key.pem",
"--ssl-certfile", "./certs/localhost+2.pem",
"--reload"
],
"django": true,
"justMyCode": true,
"python": "`${workspaceFolder}/venv/Scripts/python.exe"
}
]
}
"@ | Out-File -FilePath .vscode/launch.json -Encoding utf8
```
This allows you to:
- Run and debug Django with F5 in VS Code
- Set breakpoints in your Django code
- Automatic venv activation via the `python` path
Note: Replace `backend` with your project name if different. On Windows, the Python path uses `venv/Scripts/python.exe`.

View File

@@ -0,0 +1,200 @@
# Python Installation - Fedora/RHEL/CentOS
## Check Current Version
```bash
python3 --version
```
If you see Python 3.11+, you're good to go! [← Back to main skill](../SKILL.md#step-2-create-virtual-environment)
---
## Installation Methods
### Option 1: DNF Package Manager (Fedora)
**Fedora usually includes recent Python versions:**
```bash
sudo dnf install python3.11 python3.11-devel python3.11-pip -y
```
**For Python 3.12/3.13 (if available):**
```bash
sudo dnf install python3.13 python3.13-devel -y
```
**Verify:**
```bash
python3.13 --version
```
---
### Option 2: RHEL/CentOS (Using EPEL)
**Enable EPEL repository:**
```bash
sudo dnf install epel-release -y
sudo dnf update -y
```
**Install Python:**
```bash
sudo dnf install python3.11 python3.11-devel python3.11-pip -y
```
---
### Option 3: Build from Source (Advanced)
**Install build dependencies:**
```bash
sudo dnf groupinstall "Development Tools" -y
sudo dnf install gcc openssl-devel bzip2-devel libffi-devel zlib-devel -y
```
**Download and build Python 3.13:**
```bash
cd /tmp
wget https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz
tar xzf Python-3.13.0.tgz
cd Python-3.13.0
./configure --enable-optimizations
make -j $(nproc)
sudo make altinstall # Don't use 'install', use 'altinstall' to avoid replacing system python
```
**Verify:**
```bash
python3.13 --version
```
---
### Option 4: pyenv (Multiple Versions)
**Install dependencies:**
```bash
sudo dnf install gcc make patch zlib-devel bzip2 bzip2-devel \
readline-devel sqlite sqlite-devel openssl-devel tk-devel \
libffi-devel xz-devel -y
```
**Install pyenv:**
```bash
curl https://pyenv.run | bash
```
**Add to ~/.bashrc:**
```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
```
**Reload shell:**
```bash
source ~/.bashrc
```
**Install Python 3.13:**
```bash
pyenv install 3.13.0
pyenv global 3.13.0
```
**Verify:**
```bash
python --version
```
---
## Set Default Python Version
**Check available versions:**
```bash
ls /usr/bin/python*
```
**Set alternative:**
```bash
sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 1
sudo alternatives --config python3
```
---
## Install pip
**Usually installed with python3:**
```bash
python3 -m pip --version
```
**If missing:**
```bash
sudo dnf install python3-pip -y
```
**Upgrade pip:**
```bash
python3 -m pip install --user --upgrade pip
```
---
## Troubleshooting
### Issue: `No package python3.13 available`
**Solutions:**
1. Check Fedora version: `cat /etc/fedora-release`
2. Update system: `sudo dnf update -y`
3. Try older version: `sudo dnf install python3.11 -y`
4. Use pyenv (Option 4 above)
### Issue: `No module named 'venv'`
**Install venv (usually included):**
```bash
sudo dnf install python3.13-venv -y
```
### Issue: Development headers missing
**Install development package:**
```bash
sudo dnf install python3.13-devel -y
```
### Issue: Permission denied
**Don't use sudo with pip inside venv:**
```bash
python3 -m venv venv
source venv/bin/activate
pip install <package> # No sudo needed
```
---
## Verification Checklist
- [ ] `python3 --version` shows 3.11+
- [ ] `python3 -m venv --help` works
- [ ] `python3 -m pip --version` works
- [ ] Can create test venv: `python3 -m venv test_venv`
- [ ] Can activate: `source test_venv/bin/activate`
**Clean up test:**
```bash
rm -rf test_venv
```
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,190 @@
# Python Installation - Ubuntu/Debian
## Check Current Version
```bash
python3 --version
```
If you see Python 3.11+, you're good to go! [← Back to main skill](../SKILL.md#step-2-create-virtual-environment)
---
## Installation Methods
### Option 1: From Ubuntu PPA (Recommended for Latest Versions)
**For Python 3.13 (latest):**
```bash
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
sudo apt install python3.13 python3.13-venv python3.13-dev -y
```
**For Python 3.11:**
```bash
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
sudo apt install python3.11 python3.11-venv python3.11-dev -y
```
**Verify installation:**
```bash
python3.13 --version
```
---
### Option 2: System Package Manager (Older Versions)
**Ubuntu 22.04+ includes Python 3.10+ by default:**
```bash
sudo apt update
sudo apt install python3 python3-venv python3-pip python3-dev -y
```
**Check version:**
```bash
python3 --version
```
---
### Option 3: pyenv (Multiple Versions)
**Install dependencies:**
```bash
sudo apt update
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev
```
**Install pyenv:**
```bash
curl https://pyenv.run | bash
```
**Add to ~/.bashrc or ~/.zshrc:**
```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
```
**Reload shell:**
```bash
source ~/.bashrc # or source ~/.zshrc
```
**Install Python 3.13:**
```bash
pyenv install 3.13.0
pyenv global 3.13.0
```
**Verify:**
```bash
python --version
```
---
## Set Default Python Version
**If you installed Python 3.13 but `python3` still points to old version:**
```bash
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.13 1
sudo update-alternatives --config python3
```
**Select the number for Python 3.13**
---
## Install pip
**For Python 3.13:**
```bash
sudo apt install python3.13-distutils -y
curl -sS https://bootstrap.pypa.io/get-pip.py | python3.13
```
**Or use system package:**
```bash
sudo apt install python3-pip -y
```
**Verify:**
```bash
python3 -m pip --version
```
---
## Troubleshooting
### Issue: `E: Unable to locate package python3.13`
**Solution:** Add deadsnakes PPA (see Option 1 above)
### Issue: `No module named 'venv'`
**Install venv module:**
```bash
sudo apt install python3.13-venv -y
```
### Issue: `No module named 'distutils'`
**Install distutils:**
```bash
sudo apt install python3.13-distutils -y
```
### Issue: Build dependencies missing (for pyenv)
**Install build essentials:**
```bash
sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev -y
```
### Issue: Permission denied when installing packages
**Don't use sudo with pip!** Use virtual environments instead:
```bash
python3 -m venv venv
source venv/bin/activate
pip install <package>
```
---
## Verification Checklist
- [ ] `python3 --version` shows 3.11+
- [ ] `python3 -m venv --help` shows venv usage
- [ ] `python3 -m pip --version` works
- [ ] Can create test venv: `python3 -m venv test_venv`
- [ ] Can activate: `source test_venv/bin/activate`
**Clean up test:**
```bash
rm -rf test_venv
```
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,184 @@
# Python Installation - macOS
## Check Current Version
```bash
python3 --version
```
If you see Python 3.11+, you're good to go! [← Back to main skill](../SKILL.md#step-2-create-virtual-environment)
---
## Installation Methods
### Option 1: Homebrew (Recommended)
**Why Homebrew:**
- Easy updates: `brew upgrade python@3.13`
- Manages dependencies automatically
- Industry standard on macOS
**Install Homebrew (if not installed):**
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
**Install Python 3.13:**
```bash
brew install python@3.13
```
**Verify installation:**
```bash
python3.13 --version
# Or if it's the default:
python3 --version
```
**Add to PATH (if needed):**
```bash
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc # For M1/M2 Macs
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc # For Intel Macs
source ~/.zshrc
```
---
### Option 2: Official Python Installer
**When to use:** You want specific Python version or don't use Homebrew
**Steps:**
1. Visit [python.org/downloads](https://www.python.org/downloads/)
2. Click "Download Python 3.13.x" button
3. Open downloaded `.pkg` file
4. Follow installation wizard
5. Restart Terminal
**Verify:**
```bash
python3 --version
```
**Add to PATH (if needed):**
```bash
echo 'export PATH="/Library/Frameworks/Python.framework/Versions/3.13/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```
---
### Option 3: pyenv (Multiple Python Versions)
**Why pyenv:**
- Manage multiple Python versions side-by-side
- Easy switching between projects
- Preferred by professional developers
**Install pyenv:**
```bash
brew install pyenv
```
**Install Python 3.13:**
```bash
pyenv install 3.13.0
```
**Set as global default:**
```bash
pyenv global 3.13.0
```
**Or set for specific project:**
```bash
cd /path/to/project
pyenv local 3.13.0
```
**Configure shell (add to ~/.zshrc):**
```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
```
**Reload shell:**
```bash
source ~/.zshrc
```
**Verify:**
```bash
python --version # Should show 3.13.0
```
---
## Troubleshooting
### Issue: `command not found: python3`
**After Homebrew install:**
```bash
brew link python@3.13
```
**Check where Python is:**
```bash
which python3
brew --prefix python@3.13
```
### Issue: Multiple Python versions conflict
**List all Python installations:**
```bash
which -a python3
ls -l /usr/local/bin/python*
```
**Use specific version:**
```bash
python3.13 -m venv venv # Force Python 3.13
```
### Issue: SSL certificate errors
**Install certificates:**
```bash
/Applications/Python\ 3.13/Install\ Certificates.command
```
Or via Homebrew:
```bash
brew install openssl
```
### Issue: Xcode Command Line Tools needed
**Install:**
```bash
xcode-select --install
```
---
## Verification Checklist
- [ ] `python3 --version` shows 3.11+
- [ ] `which python3` shows installation path
- [ ] `python3 -m pip --version` works
- [ ] `python3 -m venv test_venv` creates test environment
- [ ] Can activate test venv: `source test_venv/bin/activate`
**Clean up test:**
```bash
rm -rf test_venv
```
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,267 @@
# Python Installation - Windows
## Check Current Version
**PowerShell or Command Prompt:**
```powershell
python --version
```
If you see Python 3.11+, you're good to go! [← Back to main skill](../SKILL.md#step-2-create-virtual-environment)
---
## Installation Methods
### Option 1: Official Python Installer (Recommended)
**Why this method:**
- Official releases from python.org
- Includes pip automatically
- Easy installation
**Steps:**
1. Visit [python.org/downloads](https://www.python.org/downloads/)
2. Click **"Download Python 3.13.x"** button
3. Run the downloaded `.exe` installer
**⚠️ CRITICAL: Check "Add Python to PATH"**
- This checkbox is at the bottom of the installer
- **Must check this box** or Python won't work from command line
4. Click "Install Now"
5. Wait for installation to complete
6. Click "Close"
**Verify installation:**
```powershell
python --version
pip --version
```
---
### Option 2: Microsoft Store (Windows 10/11)
**Why this method:**
- Easiest installation
- Automatic PATH configuration
- Auto-updates through Microsoft Store
**Steps:**
1. Open **Microsoft Store** app
2. Search for "Python 3.13"
3. Click **"Get"** or **"Install"**
4. Wait for installation
5. Restart terminal
**Verify:**
```powershell
python --version
```
---
### Option 3: Chocolatey Package Manager
**Why this method:**
- Command-line package management (like Homebrew on macOS)
- Good for automated setups
- Easy updates: `choco upgrade python`
**Install Chocolatey first:**
Open **PowerShell as Administrator** and run:
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
```
**Install Python:**
```powershell
choco install python --version=3.13.0
```
**Verify:**
```powershell
python --version
```
---
### Option 4: Scoop Package Manager
**Why this method:**
- Lightweight package manager
- No admin rights required
- Clean installations
**Install Scoop:**
```powershell
irm get.scoop.sh | iex
```
**Install Python:**
```powershell
scoop install python
```
**Verify:**
```powershell
python --version
```
---
## Configure PATH (If Python Not Found)
### Check if Python is in PATH
**Open Command Prompt and run:**
```cmd
where python
```
**If nothing appears, Python is not in PATH.**
### Add Python to PATH Manually
**Find Python installation location:**
- Official installer: `C:\Users\<YourName>\AppData\Local\Programs\Python\Python313\`
- Microsoft Store: `C:\Users\<YourName>\AppData\Local\Microsoft\WindowsApps\`
**Add to PATH:**
1. Open **Start Menu**
2. Search "Environment Variables"
3. Click **"Edit the system environment variables"**
4. Click **"Environment Variables"** button
5. Under "User variables", select **"Path"**
6. Click **"Edit"**
7. Click **"New"**
8. Add Python paths:
- `C:\Users\<YourName>\AppData\Local\Programs\Python\Python313\`
- `C:\Users\<YourName>\AppData\Local\Programs\Python\Python313\Scripts\`
9. Click **"OK"** on all dialogs
10. **Restart terminal/PowerShell**
**Verify:**
```powershell
python --version
```
---
## Troubleshooting
### Issue: `python: command not found`
**Solution 1: Use `py` launcher instead**
```powershell
py --version
py -m venv venv
```
**Solution 2: Add to PATH** (see section above)
**Solution 3: Reinstall Python**
- Uninstall current Python
- Reinstall and **check "Add Python to PATH"**
### Issue: Multiple Python versions installed
**List all versions:**
```powershell
py --list
```
**Use specific version:**
```powershell
py -3.13 --version
py -3.13 -m venv venv
```
### Issue: PowerShell Execution Policy Error
**When activating venv:**
```
venv\Scripts\Activate.ps1 : File cannot be loaded because running scripts is disabled
```
**Solution:**
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
**Then retry activation:**
```powershell
venv\Scripts\Activate.ps1
```
### Issue: `pip` not found
**Use python -m pip instead:**
```powershell
python -m pip --version
python -m pip install --upgrade pip
```
### Issue: Long path errors
**Enable long paths in Windows:**
Open **PowerShell as Administrator**:
```powershell
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
```
Restart computer.
---
## Using Windows Subsystem for Linux (WSL)
**Alternative: Use Linux Python on Windows**
**Install WSL:**
```powershell
wsl --install
```
**Install Ubuntu:**
```powershell
wsl --install -d Ubuntu
```
**Then follow:** [linux-ubuntu.md](linux-ubuntu.md) for Python installation
---
## Verification Checklist
- [ ] `python --version` shows 3.11+ (or `py --version`)
- [ ] `pip --version` works (or `py -m pip --version`)
- [ ] `python -m venv test_venv` creates test environment
- [ ] Can activate test venv: `test_venv\Scripts\activate`
- [ ] Prompt shows `(test_venv)` prefix
**Clean up test:**
```powershell
rmdir /s test_venv
```
---
## Development Tools (Optional)
**Install Windows Terminal** (better than Command Prompt):
- Download from Microsoft Store
- Or: https://aka.ms/terminal
**Install Git for Windows:**
- Download from: https://git-scm.com/download/win
**Install VS Code:**
- Download from: https://code.visualstudio.com/
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""
Script to create .gitignore file from template.
Usage:
python create_gitignore.py --output /path/to/project
python create_gitignore.py --output .
"""
import argparse
import os
import shutil
from pathlib import Path
def create_gitignore(output_dir: str) -> None:
"""
Copy .gitignore template to the specified output directory.
Args:
output_dir: Directory where .gitignore should be created
"""
# Get the directory where this script is located
script_dir = Path(__file__).parent
skill_dir = script_dir.parent
# Path to the template
template_path = skill_dir / "examples" / ".gitignore-template"
# Validate template exists
if not template_path.exists():
raise FileNotFoundError(
f"Template not found at: {template_path}\n"
f"Expected location: .claude/skills/django-setup/examples/.gitignore-template"
)
# Create output directory if it doesn't exist
output_path = Path(output_dir).resolve()
output_path.mkdir(parents=True, exist_ok=True)
# Destination path
gitignore_path = output_path / ".gitignore"
# Check if .gitignore already exists
if gitignore_path.exists():
print(f"⚠️ .gitignore already exists at: {gitignore_path}")
print("❌ Script should only be used when .gitignore does not exist.")
print("💡 Use manual merging to add missing entries from the template.")
exit(1)
# Copy the template
shutil.copy2(template_path, gitignore_path)
print(f"✅ Created .gitignore at: {gitignore_path}")
print(f"📋 Copied from template: {template_path}")
def main():
parser = argparse.ArgumentParser(
description="Create .gitignore file from template for Django projects",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Create .gitignore in current directory
python create_gitignore.py --output .
# Create .gitignore in specific project directory
python create_gitignore.py --output /path/to/project
# Create .gitignore in parent directory
python create_gitignore.py --output ..
"""
)
parser.add_argument(
'--output',
type=str,
required=True,
help='Directory where .gitignore should be created (e.g., . for current directory)'
)
args = parser.parse_args()
try:
create_gitignore(args.output)
except FileNotFoundError as e:
print(f"❌ Error: {e}")
exit(1)
except Exception as e:
print(f"❌ Unexpected error: {e}")
exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,480 @@
# Troubleshooting: Django Errors
[← Back to main skill](../SKILL.md)
---
## Issue: `django-admin: command not found` {#django-admin}
**After installing Django, command doesn't work**
### Solutions:
**Ensure venv is activated:**
```bash
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
```
**Use `python -m django` instead:**
```bash
python -m django --version
python -m django startproject myproject
```
**Check Django is installed:**
```bash
pip list | grep Django
# or
pip show Django
```
**Reinstall Django:**
```bash
pip install --force-reinstall Django
```
---
## Issue: Port 8000 Already in Use {#port-in-use}
**Error:**
```
Error: That port is already in use.
```
### Solutions:
**Use different port:**
```bash
python manage.py runserver 8001
python manage.py runserver 0.0.0.0:8080
```
**Kill process using port 8000:**
**macOS/Linux:**
```bash
lsof -ti:8000 | xargs kill -9
```
**Windows (PowerShell):**
```powershell
netstat -ano | findstr :8000
# Note the PID, then:
taskkill /PID <pid> /F
```
**Windows (Command Prompt):**
```cmd
FOR /F "tokens=5" %P IN ('netstat -ano ^| findstr :8000') DO TaskKill /PID %P /F
```
---
## Issue: `ModuleNotFoundError: No module named 'django'`
**Django installed but Python can't find it**
### Solutions:
**Verify venv is activated:**
```bash
which python # Should point to venv/bin/python
echo $VIRTUAL_ENV # Should show venv path
```
**Check Django installation:**
```bash
pip list
pip show Django
```
**Install Django in venv:**
```bash
source venv/bin/activate
pip install Django
```
**Check you're using venv Python:**
```bash
python --version
which python
```
---
## Issue: `django.core.exceptions.ImproperlyConfigured`
**Common misconfigurations**
### `SECRET_KEY` not set
**Error:**
```
ImproperlyConfigured: The SECRET_KEY setting must not be empty.
```
**Solution:**
- Don't delete SECRET_KEY from settings.py
- If using environment variables, ensure .env file exists
### Database configuration error
**Error:**
```
ImproperlyConfigured: settings.DATABASES is improperly configured
```
**Solution - Check database settings:**
```python
# settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
```
---
## Issue: Migrations Not Applying
**Error:**
```
django.db.utils.OperationalError: no such table
```
### Solutions:
**Run migrations:**
```bash
python manage.py migrate
```
**Check migration files exist:**
```bash
ls */migrations/
# Should see 0001_initial.py files
```
**Reset database (development only!):**
```bash
rm db.sqlite3
python manage.py migrate
```
**Make migrations if they don't exist:**
```bash
python manage.py makemigrations
python manage.py migrate
```
---
## Issue: Static Files Not Loading
**CSS/JS files show 404 in browser**
### Solutions:
**Run collectstatic:**
```bash
python manage.py collectstatic
```
**Check STATIC_URL in settings.py:**
```python
STATIC_URL = '/static/'
```
**For development, ensure DEBUG=True:**
```python
DEBUG = True
```
**Check INSTALLED_APPS includes:**
```python
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
]
```
---
## Issue: Template Not Found
**Error:**
```
TemplateDoesNotExist at /path/
```
### Solutions:
**Check template path:**
```python
# settings.py
TEMPLATES = [
{
'DIRS': [BASE_DIR / 'templates'], # Add this
...
},
]
```
**Create templates directory:**
```bash
mkdir -p templates
```
**Check template name matches:**
```python
# views.py
return render(request, 'index.html') # Must match file name exactly
```
---
## Issue: ALLOWED_HOSTS Error in Production
**Error:**
```
Invalid HTTP_HOST header: 'yourdomain.com'. You may need to add 'yourdomain.com' to ALLOWED_HOSTS.
```
### Solution:
**Add domain to ALLOWED_HOSTS:**
```python
# settings.py
DEBUG = False # In production
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
```
**For development:**
```python
DEBUG = True
ALLOWED_HOSTS = [] # Empty list allows localhost automatically
```
---
## Issue: CSRF Verification Failed
**Error:**
```
Forbidden (403)
CSRF verification failed. Request aborted.
```
### Solutions:
**Ensure CSRF middleware is enabled:**
```python
# settings.py
MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
```
**Include CSRF token in forms:**
```html
<form method="post">
{% csrf_token %}
...
</form>
```
**For AJAX, include CSRF token in headers:**
```javascript
// Get CSRF token from cookie
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
fetch('/api/endpoint/', {
method: 'POST',
headers: {
'X-CSRFToken': csrftoken
}
})
```
---
## Issue: Admin Interface Not Working
**Can't access /admin/**
### Solutions:
**Run migrations:**
```bash
python manage.py migrate
```
**Create superuser:**
```bash
python manage.py createsuperuser
```
**Check URL configuration:**
```python
# urls.py
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
]
```
**Ensure admin app is installed:**
```python
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
]
```
---
## Issue: Project Won't Start After Renaming
**Renamed project but errors occur**
### Solution:
**Update references in these files:**
**manage.py:**
```python
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'new_name.settings')
```
**asgi.py:**
```python
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'new_name.settings')
```
**wsgi.py:**
```python
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'new_name.settings')
```
**Rename project directory itself**
---
## Issue: Circular Import Errors
**Error:**
```
ImportError: cannot import name 'X' from partially initialized module 'Y'
```
### Solutions:
**Avoid circular imports:**
```python
# ❌ Bad - circular import
# models.py
from .views import something
# views.py
from .models import Model
```
**Use lazy imports:**
```python
# ✅ Good - import inside function
def my_view(request):
from .models import Model # Import here
...
```
**Or use Django's get_model:**
```python
from django.apps import apps
Model = apps.get_model('app_name', 'ModelName')
```
---
## Issue: `SyntaxError` in settings.py
**Error:**
```
SyntaxError: invalid syntax
```
### Solutions:
**Check Python version:**
```bash
python --version # Should be 3.8+
```
**Look for common syntax errors:**
```python
# ❌ Missing comma
INSTALLED_APPS = [
'django.contrib.admin' # Missing comma!
'django.contrib.auth',
]
# ✅ Correct
INSTALLED_APPS = [
'django.contrib.admin', # Comma here
'django.contrib.auth',
]
```
**Validate Python syntax:**
```bash
python -m py_compile backend/settings.py
```
---
## Quick Diagnostic Commands
**Check Django installation:**
```bash
python -m django --version
```
**Check Python version:**
```bash
python --version
```
**Run system checks:**
```bash
python manage.py check
python manage.py check --deploy
```
**List installed packages:**
```bash
pip list
```
**Check migrations status:**
```bash
python manage.py showmigrations
```
**Test database connection:**
```bash
python manage.py dbshell
```
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,386 @@
# Troubleshooting: pip Problems
[← Back to main skill](../SKILL.md)
---
## Issue: `pip: command not found` {#pip-not-found}
**After activating venv, pip doesn't work**
### Solutions:
**Use `python -m pip` instead:**
```bash
python -m pip --version
python -m pip install Django
python -m pip install --upgrade pip
```
**Ensure venv is activated:**
```bash
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
```
**Reinstall pip in venv:**
```bash
python -m ensurepip --upgrade
```
---
## Issue: `pip install` Requires sudo
**Error:**
```
ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied
```
### Solution:
**❌ NEVER use sudo with pip!**
**✅ Use virtual environment instead:**
```bash
# Create and activate venv first
python3 -m venv venv
source venv/bin/activate
# Now install without sudo
pip install Django
```
**Why no sudo:**
- Pollutes system Python
- Breaks system tools
- Security risk
- Conflicts with package manager
---
## Issue: SSL Certificate Errors
**Error:**
```
SSL: CERTIFICATE_VERIFY_FAILED
```
### Solutions:
**macOS - Install certificates:**
```bash
/Applications/Python\ 3.13/Install\ Certificates.command
```
**Or install certifi:**
```bash
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org certifi
```
**Ubuntu/Debian:**
```bash
sudo apt install ca-certificates
sudo update-ca-certificates
```
**Temporary workaround (not recommended):**
```bash
pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org Django
```
---
## Issue: pip is Outdated
**Warning:**
```
WARNING: You are using pip version X.X.X; however, version Y.Y.Y is available.
```
### Solution:
**Upgrade pip:**
```bash
python -m pip install --upgrade pip
```
**If that fails:**
```bash
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
rm get-pip.py
```
---
## Issue: Package Installation Fails
**Error:**
```
ERROR: Could not find a version that satisfies the requirement <package>
```
### Solutions:
**Check package name spelling:**
```bash
# Wrong
pip install django-rest-framework
# Correct
pip install djangorestframework
```
**Check Python version compatibility:**
```bash
python --version # Some packages require Python 3.11+
```
**Try older package version:**
```bash
pip install "Django<5.0" # Install Django 4.x
```
**Update pip and setuptools:**
```bash
pip install --upgrade pip setuptools wheel
```
---
## Issue: Conflicting Dependencies
**Error:**
```
ERROR: package-a 1.0 has requirement package-b>=2.0, but you'll have package-b 1.5
```
### Solutions:
**Let pip resolve (pip 20.3+):**
```bash
pip install --upgrade <package>
```
**Install specific compatible versions:**
```bash
pip install package-a package-b==2.0
```
**Use pip-tools for dependency management:**
```bash
pip install pip-tools
# Create requirements.in with your deps
pip-compile requirements.in
pip-sync requirements.txt
```
**Nuclear option - recreate venv:**
```bash
deactivate
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
---
## Issue: Building Wheels Failed
**Error:**
```
Failed building wheel for <package>
```
### Solutions:
**Install build dependencies:**
**macOS:**
```bash
xcode-select --install
brew install openssl
```
**Ubuntu/Debian:**
```bash
sudo apt install python3-dev build-essential libssl-dev libffi-dev -y
```
**Fedora/RHEL:**
```bash
sudo dnf install python3-devel gcc openssl-devel libffi-devel -y
```
**Windows:**
- Install Microsoft C++ Build Tools
- Download from: https://visualstudio.microsoft.com/visual-cpp-build-tools/
**Use pre-built wheels:**
```bash
pip install --only-binary :all: <package>
```
---
## Issue: `externally-managed-environment` Error
**Error (Python 3.11+ on some Linux distros):**
```
error: externally-managed-environment
This environment is externally managed
```
### Solution:
**✅ Use virtual environment (recommended):**
```bash
python3 -m venv venv
source venv/bin/activate
pip install Django
```
**Or use `--break-system-packages` (not recommended):**
```bash
pip install --break-system-packages Django # ⚠️ Use at own risk
```
---
## Issue: Slow Download Speed
**Pip takes forever to download packages**
### Solutions:
**Use faster mirror (if in China):**
```bash
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Django
```
**Increase timeout:**
```bash
pip install --timeout=1000 Django
```
**Use pip cache:**
```bash
pip install Django # First time (slow)
pip install Django # Second time (fast, uses cache)
```
---
## Issue: Hash Mismatch Error
**Error:**
```
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE
```
### Solutions:
**Regenerate requirements.txt:**
```bash
pip freeze > requirements.txt
```
**Install without hash checking (temporary):**
```bash
pip install --no-deps -r requirements.txt
```
**Clear pip cache:**
```bash
pip cache purge
```
---
## Issue: ImportError After Installing Package
**Package installs but can't import**
### Solutions:
**Verify venv is activated:**
```bash
which python # Should point to venv
pip list # Should show installed package
```
**Check package name vs import name:**
```bash
# Install name: django-cors-headers
pip install django-cors-headers
# Import name: corsheaders
import corsheaders # ← Different!
```
**Restart Python shell:**
```bash
exit() # Exit Python shell
python # Start fresh
import django # Try again
```
---
## Issue: Multiple pip Versions
**`pip` points to wrong Python version**
### Solution:
**Always use `python -m pip`:**
```bash
# Instead of:
pip install Django
# Use:
python -m pip install Django
```
**Or specify Python version:**
```bash
python3.13 -m pip install Django
```
---
## Best Practices
**Always use virtual environments**
```bash
python3 -m venv venv
source venv/bin/activate
```
**Keep pip updated**
```bash
pip install --upgrade pip
```
**Pin versions in production**
```bash
# requirements.txt
Django==5.0.1
djangorestframework==3.14.0
```
**Use requirements.txt**
```bash
pip freeze > requirements.txt
pip install -r requirements.txt
```
**Don't mix conda and pip** (if using Anaconda)
- Use conda for conda packages
- Use pip only for packages not in conda
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,376 @@
# Troubleshooting: Virtual Environment Issues
[← Back to main skill](../SKILL.md)
---
## Issue: `ensurepip is not available` {#ensurepip}
**Full error:**
```
Error: Command '[...]/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1
```
### Solutions:
**Ubuntu/Debian:**
```bash
sudo apt install python3.13-venv python3.13-distutils -y
```
**macOS (Homebrew):**
```bash
brew reinstall python@3.13
```
**Windows:**
- Reinstall Python with "pip" option checked
- Or download get-pip.py: https://bootstrap.pypa.io/get-pip.py
---
## Issue: PowerShell Execution Policy {#powershell-execution-policy}
**Error:**
```
venv\Scripts\Activate.ps1 cannot be loaded because running scripts is disabled on this system
```
### Solution:
**Allow scripts for current user:**
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
**Then retry activation:**
```powershell
venv\Scripts\Activate.ps1
```
**Verify policy:**
```powershell
Get-ExecutionPolicy -List
```
---
## Issue: Virtual Environment Not Activating
**Symptoms:**
- No `(venv)` prefix in prompt
- `which python` still points to system Python
### Solutions:
**macOS/Linux - Check activation command:**
```bash
source venv/bin/activate # Correct
. venv/bin/activate # Also works
bash venv/bin/activate # Wrong - don't use bash
```
**Windows - Use correct script:**
```powershell
# PowerShell
venv\Scripts\Activate.ps1
# Command Prompt
venv\Scripts\activate.bat
# Git Bash
source venv/Scripts/activate
```
**Verify activation:**
```bash
which python # Should point to venv/bin/python
echo $VIRTUAL_ENV # Should show venv path
```
---
## Issue: Permission Denied on Activation {#permission-denied}
**Error (macOS/Linux):**
```
bash: venv/bin/activate: Permission denied
```
### Solution:
**Make script executable:**
```bash
chmod +x venv/bin/activate
source venv/bin/activate
```
**Or recreate venv:**
```bash
rm -rf venv
python3 -m venv venv
```
---
## Issue: `venv` Module Not Found
**Error:**
```
No module named venv
```
### Solutions:
**Ubuntu/Debian:**
```bash
sudo apt install python3.13-venv -y
```
**Fedora/RHEL:**
```bash
sudo dnf install python3.13-venv -y
```
**macOS:**
```bash
# Reinstall Python via Homebrew
brew reinstall python@3.13
# Or install from python.org
```
**Windows:**
- Usually included by default
- Reinstall Python if missing
---
## Issue: Wrong Python Version in venv
**Symptom:**
```bash
(venv) $ python --version
Python 3.8.10 # But you wanted 3.13!
```
### Solution:
**Delete and recreate with specific version:**
```bash
deactivate # If currently activated
rm -rf venv
# Specify exact Python version
python3.13 -m venv venv # macOS/Linux
py -3.13 -m venv venv # Windows
```
**Verify before activating:**
```bash
venv/bin/python --version # Check version first
source venv/bin/activate # Then activate
```
---
## Issue: Can't Deactivate venv
**Symptom:**
- `deactivate` command doesn't work
- Still see `(venv)` in prompt
### Solutions:
**Try deactivate function:**
```bash
deactivate
```
**If that fails, just close terminal:**
- Exit terminal/shell
- Open new terminal
- venv won't be active in new session
**Or manually unset variables:**
```bash
unset VIRTUAL_ENV
export PATH="$OLD_PATH"
```
---
## Issue: venv Created in Wrong Location
**Symptom:**
- venv created in home directory instead of project
- venv in system location
### Solution:
**Delete misplaced venv:**
```bash
rm -rf ~/venv # Or wherever it was created
```
**Navigate to project first:**
```bash
cd /path/to/your/project
pwd # Verify you're in correct directory
python3 -m venv venv # Now create here
```
---
## Issue: `pip` Not Found After Activation
**Error:**
```
(venv) $ pip --version
pip: command not found
```
### Solutions:
**Use `python -m pip` instead:**
```bash
python -m pip --version
python -m pip install <package>
```
**Reinstall pip in venv:**
```bash
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
rm get-pip.py
```
**Or recreate venv:**
```bash
deactivate
rm -rf venv
python3 -m venv venv --clear
```
---
## Issue: venv Taking Too Much Space
**Symptom:**
- venv folder is several GB
- Too many cached packages
### Solutions:
**Clear pip cache:**
```bash
pip cache purge
```
**Remove unnecessary packages:**
```bash
pip list # See what's installed
pip uninstall <package>
```
**Use `--no-cache-dir` when installing:**
```bash
pip install --no-cache-dir Django
```
**Typical venv sizes:**
- Minimal Django: ~100-200 MB
- Full-featured project: ~500 MB - 1 GB
- If >2 GB, something is wrong
---
## Issue: Can't Delete venv Folder
**Windows error:**
```
Access denied
File in use
```
### Solutions:
**Deactivate first:**
```bash
deactivate
```
**Close all terminals/IDEs using that folder**
**Windows - use PowerShell as Admin:**
```powershell
Remove-Item -Recurse -Force venv
```
**Or use File Explorer:**
- Right-click venv folder
- Properties → Security → Advanced
- Take ownership
- Delete
---
## Issue: IDE Not Recognizing venv
**VS Code, PyCharm not using venv Python**
### Solutions:
**VS Code:**
1. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac)
2. Type "Python: Select Interpreter"
3. Choose `./venv/bin/python`
**PyCharm:**
1. File → Settings (or Preferences on Mac)
2. Project → Python Interpreter
3. Click gear icon → Add
4. Select "Existing environment"
5. Browse to `venv/bin/python`
---
## Best Practices to Avoid Issues
**Always activate before installing packages**
```bash
source venv/bin/activate # Activate first
pip install Django # Then install
```
**One venv per project**
```
project1/
└── venv/
project2/
└── venv/
```
**Don't commit venv to git**
```gitignore
venv/
.venv/
env/
ENV/
```
**Document Python version in README**
```markdown
## Requirements
- Python 3.13+
```
**Use requirements.txt**
```bash
pip freeze > requirements.txt
# Others can: pip install -r requirements.txt
```
---
[← Back to django-project-setup](../SKILL.md)

View File

@@ -0,0 +1,45 @@
# React Allauth Skill (Frontend)
Plug google/django-allauth headless authentication flows into a Vite React app: copies the React SPA example modules, wires auth context/routes, fixes provider URLs, adds proxying, and provides Playwright tests and styling references.
## What This Skill Provides
- Copies allauth React SPA modules into `frontend/src/user_management/`, renames to `.jsx`, and integrates auth routes with your existing router.
- Configures API base URLs, CSRF handling, and social callback URLs to point at the Django backend (`/_allauth/...`).
- Adds Vite proxy rules for `/_allauth` (and expects existing `/api` proxy) to `https://localhost:8000` with self-signed certs.
- Wraps the app in `AuthContextProvider`, adds auth-aware nav, and removes demo routes (e.g., `/calculator`).
- Supports multi-step flows (email verification, passkeys) with pending-flow redirects.
- Bundles Playwright end-to-end tests for signup/login/logout/code-login/password-reset.
- Includes a styling reference listing all 35 auth components needing UI polish.
## Prerequisites
- React + Vite frontend already set up (see `react-setup` skill).
- Django backend with django-allauth headless enabled and HTTPS at `https://localhost:8000`.
- mkcert-based HTTPS for frontend (`https://localhost:5173`).
- React Router in use; API config exporting `API_BASE_URL`.
## Setup Summary (see SKILL.md for line-by-line edits)
1) **Clone & copy example modules** from `django-allauth/examples/react-spa/frontend/src` into `frontend/src/user_management/` (files renamed `.jsx`).
2) **Install dependency**: `npm --prefix ./frontend install @github/webauthn-json`.
3) **App wrapper**: wrap your app in `<AuthContextProvider>` in `frontend/src/App.jsx`.
4) **API base URL**: in `user_management/lib/allauth.jsx`, import `API_BASE_URL` and prefix `/_allauth/${Client.BROWSER}/v1` with it.
5) **Routes**: create `frontend/src/router/AuthRouter.jsx` exposing `createAuthRoutes(config)`; merge into `createAppRouter` alongside your existing routes. Remove demo `/calculator` route.
6) **Redirects**: set `LOGIN_REDIRECT_URL = '/'`; update password-change/other redirects from `/calculator` to your desired path (default dashboard/home).
7) **Social callback fix**: set `callback_url: callbackURL` in `redirectToProvider` so backend URL is respected.
8) **Vite proxy**: add `/_allauth` proxy to `vite.config.js` targeting backend with `secure:false`.
9) **Auth-aware nav**: surface Login/Logout links conditioned on `useAuthStatus` (navbar or Home fallback).
10) **Flow handling**: add pending-flow redirects in signup/passkey/email verification and `AuthChangeRedirector`.
11) **Styling reference**: copy `references/styling-guide.md` to project root as `react-allauth-styling-reference.md` for later UI work.
12) **Tests**: run Playwright suite in `scripts/test_auth_flows.py` (requires backend + frontend running, pytest<9, playwright+chromium).
## Outputs/Artifacts
- Auth modules under `frontend/src/user_management/` wired to your router.
- Vite proxy updated for `/_allauth`.
- Auth context wrapping `App`.
- Optional styling reference file in project root.
- Playwright E2E tests ready to validate flows.
## Notes & Gotchas
- Backend must expose headless endpoints at `/_allauth/...` and serve email links pointing to the frontend (e.g., `https://localhost:5173`).
- Keep AUTH flows on HTTPS; proxy uses `secure:false` to accept mkcert certs.
- Tests expect email backend to write files to `sent_emails/`; adjust if using SMTP.
- If renaming frontend host/port, update `API_BASE_URL`, email links, and test selectors accordingly.

View File

@@ -0,0 +1,587 @@
---
name: react-allauth
description: Configure React frontend with django-allauth headless API integration, including authentication UI, auth state management, protected routes, and social authentication flows
---
## Purpose
Configure a React frontend application to integrate with django-allauth's headless API, enabling complete authentication workflows including signup, login, email verification, password reset, and social authentication. This skill handles the entire setup process from copying authentication modules to validating flows with automated testing.
## Prerequisites
Before starting this configuration, ensure the following requirements are met:
- **React project with Vite** - A React frontend application initialized with Vite
- **Django backend with django-allauth** - Django backend configured with django-allauth headless API (in settings.py - Look for allauth in INSTALLED_APPS)
- **HTTPS development environment** - Both frontend and backend running over HTTPS (mkcert recommended for local SSL certificates)
- **React Router** - Project uses `react-router-dom` for routing
- **API configuration** - An `API_BASE_URL` constant exported from a config file (typically `src/config/api.js` or `src/config/api.jsx`)
- **Project structure** - Frontend source code located in `frontend/src/` with standard Vite directory structure
## Steps Overview
1. Clone Repository and Copy Authentication Modules
2. Install Required Dependencies
3. Update App.jsx to Include Authentication Context
4. Configure API Base URL in allauth.jsx
5. Update Redirect URLs
6. Copy Authentication Router and Integrate Routes
7. Fix Social Authentication Callback URL
8. Configure Vite Proxy for Authentication Endpoints
9. Add Auth-Aware Navigation Link
10. Enable Flow-Based Signup Navigation
11. Validate Authentication Flows with Automated Testing
12. Copy Styling Reference Guide
13. Stop Background Tasks
---
### Step 1: Clone Repository and Copy Authentication Modules
Clone the django-allauth repository at the project root:
```bash
git clone https://github.com/pennersr/django-allauth
```
Refactor authentication components by renaming `.js` files to `.jsx`:
```bash
find django-allauth/examples/react-spa/frontend/src/ -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.jsx"' {} \;
```
Copy the authentication modules into the React project:
```bash
mkdir -p frontend/src/user_management
find django-allauth/examples/react-spa/frontend/src/ -mindepth 1 -maxdepth 1 -type d -exec cp -r {} frontend/src/user_management/ \;
```
This creates a `user_management` directory in the React project and copies all authentication-related folders from the cloned repository. The `django-allauth/` directory remains available for later steps in this skill.
---
### Step 2: Install Required Dependencies
Install the WebAuthn dependency required by the authentication modules:
```bash
npm --prefix ./frontend install @github/webauthn-json
```
---
### Step 3: Update App.jsx to Include Authentication Context
**File:** `frontend/src/App.jsx`
Import the `AuthContextProvider` and wrap the app's content with it:
```jsx
import { AuthContextProvider } from './user_management/auth'
```
Wrap the existing app content (typically the router) with `<AuthContextProvider>`:
```jsx
<AuthContextProvider>
{/* Existing app content */}
</AuthContextProvider>
```
---
### Step 4: Configure API Base URL in allauth.jsx
**File:** `frontend/src/user_management/lib/allauth.jsx`
After the `getCSRFToken` import, add:
```jsx
import { API_BASE_URL } from '../../config/api'
```
Then update the API endpoint path from:
```jsx
`/_allauth/${Client.BROWSER}/v1`
```
To:
```jsx
`${API_BASE_URL}/_allauth/${Client.BROWSER}/v1`
```
---
### Step 5: Update Redirect URLs
Update redirect paths from `/calculator` to `/dashboard`:
**File:** `frontend/src/user_management/auth/routing.jsx`
Change the `LOGIN_REDIRECT_URL` path to:
```jsx
LOGIN_REDIRECT_URL: '/'
```
**File:** `frontend/src/user_management/account/ChangePassword.jsx`
Replace any occurrence of `'/calculator'` with `'/dashboard'`
---
### Step 6: Copy Authentication Router and Integrate Routes
Copy the authentication router file and clean up the cloned repository:
```bash
cp django-allauth/examples/react-spa/frontend/src/Router.jsx frontend/src/router/AuthRouter.jsx && rm -rf django-allauth
```
**File:** `frontend/src/router/AuthRouter.jsx`
Update all import paths to use the `user_management` directory:
Change:
```jsx
import { AuthChangeRedirector, AnonymousRoute, AuthenticatedRoute } from './auth'
```
To:
```jsx
import { AuthChangeRedirector, AnonymousRoute, AuthenticatedRoute } from '../user_management/auth'
```
Update all component imports (like `Login`, `Signup`, `ChangeEmail`, etc.) from relative paths to use `user_management`:
Change:
```jsx
import Login from './account/Login'
import Signup from './account/Signup'
// ... etc
```
To:
```jsx
import Login from '../user_management/account/Login'
import Signup from '../user_management/account/Signup'
// ... etc
```
Update the `Root` import:
```jsx
import Root from '../layouts/Root'
```
Update the `useConfig` import:
```jsx
import { useConfig } from '../user_management/auth/hooks'
```
**File:** `frontend/src/router/AppRoutes.jsx`
Import and integrate authentication routes into `createAppRouter`:
```jsx
import Root from "../layouts/Root";
import Home from "../pages/Home";
import { createAuthRoutes } from './AuthRouter';
export function createAppRouter(config) {
const authRoutes = createAuthRoutes(config);
return [
{
path: "/",
element: <Root />,
children: [
{
path: "/",
element: <Home />,
},
...authRoutes
],
},
];
}
```
**File:** `frontend/src/router/AuthRouter.jsx`
Rename the exported function and export the routes array:
Change:
```jsx
function createRouter (config) {
return createBrowserRouter([
{
path: '/',
element: <AuthChangeRedirector><Root /></AuthChangeRedirector>,
children: [
// ... routes
]
}
])
}
export default function Router () {
const [router, setRouter] = useState(null)
const config = useConfig()
useEffect(() => {
setRouter(createRouter(config))
}, [config])
return router ? <RouterProvider router={router} /> : null
}
```
To:
```jsx
export function createAuthRoutes (config) {
return [
// ... all the route objects from the children array
]
}
```
Remove the `/calculator` route as it's not needed.
---
### Step 7: Fix Social Authentication Callback URL
**File:** `frontend/src/user_management/lib/allauth.jsx`
Find the `redirectToProvider` function and update the `callback_url` parameter.
Change:
```jsx
callback_url: window.location.protocol + '//' + window.location.host + callbackURL,
```
To:
```jsx
callback_url: callbackURL,
```
This configuration ensures social authentication callbacks use the correct backend URL instead of the frontend host.
---
### Step 8: Configure Vite Proxy for Authentication Endpoints
**File:** `frontend/vite.config.js`
Add the `/_allauth` proxy configuration to forward authentication requests to the Django backend.
Add to the `proxy` object:
```js
'/_allauth': {
target: 'https://localhost:8000',
changeOrigin: true,
secure: false, // Allow self-signed certificates
},
```
**Expected result:**
```js
proxy: {
'/api': {
target: 'https://localhost:8000',
changeOrigin: true,
secure: false,
},
'/_allauth': {
target: 'https://localhost:8000',
changeOrigin: true,
secure: false,
},
}
```
---
### Step 9: Add Auth-Aware Navigation Link
First, search the project to determine if a navbar or header component exists.
#### If a navbar component exists:
Import the auth status helper and toggle the navigation link based on whether the user is logged in:
```jsx
import { useAuthStatus } from "@/user_management/auth";
import { Link } from "react-router-dom";
const [, authInfo] = useAuthStatus();
{authInfo.isAuthenticated ? (
<Link to="/account/logout">
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Logout
</NavigationMenuLink>
</Link>
) : (
<Link to="/account/login">
<NavigationMenuLink className={navigationMenuTriggerStyle()}>
Login
</NavigationMenuLink>
</Link>
)}
```
#### If NO navbar component exists:
Add auth-aware navigation links to the landing page.
**File:** `frontend/src/pages/Home.jsx`
Import the required dependencies at the top:
```jsx
import { useAuthStatus } from "@/user_management/auth";
import { Link } from "react-router-dom";
```
Add the navigation links in the component JSX:
```jsx
const [, authInfo] = useAuthStatus();
return (
<div>
<nav style={{ padding: '1rem', borderBottom: '1px solid #ccc' }}>
{authInfo.isAuthenticated ? (
<Link to="/account/logout" style={{ marginRight: '1rem' }}>
Logout
</Link>
) : (
<Link to="/account/login" style={{ marginRight: '1rem' }}>
Login
</Link>
)}
</nav>
{/* Rest of Home page content */}
</div>
);
```
**Note:** Linking to `/account/logout` ensures authenticated users reach the confirmation screen before finalizing the logout. Anonymous visitors continue to see the Login link.
---
### Step 10: Enable Flow-Based Signup Navigation
This step configures multi-step signup flows (like email verification + passkey creation) to navigate correctly between steps without intermediate redirects.
#### Step 10.1: Configure Signup Screens to Handle Pending Flows
**Files:**
- `frontend/src/user_management/account/Signup.jsx`
- `frontend/src/user_management/mfa/SignupByPasskey.jsx`
Add the following imports at the top of each signup component:
```jsx
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { pathForFlow } from '../auth'
```
Inside each component, instantiate the navigate function:
```jsx
const navigate = useNavigate()
```
Add a `useEffect` hook that watches for pending flows in the response:
```jsx
useEffect(() => {
if (response.content) {
const pending = response.content?.data?.flows?.find(flow => flow.is_pending)
if (pending) {
navigate(pathForFlow(pending), { replace: true })
}
}
}, [response.content, navigate])
```
This configuration ensures users are redirected to the next step in the signup flow (e.g., email verification) without leaving the signup page in the history stack.
#### Step 10.2: Update Authentication Redirector for Pending Flows
**File:** `frontend/src/user_management/auth/routing.jsx`
Update the `AuthChangeRedirector` component to check for pending flows before redirecting to the default login redirect URL.
In the `LOGGED_IN` branch, add logic to call `pathForPendingFlow(auth)` before defaulting to `LOGIN_REDIRECT_URL`:
```jsx
if (auth.status === AuthStatus.LOGGED_IN) {
const pendingPath = pathForPendingFlow(auth)
if (pendingPath) {
navigate(pendingPath, { replace: true })
} else {
navigate(LOGIN_REDIRECT_URL, { replace: true })
}
}
```
This logic prevents users from being redirected to the dashboard when pending authentication steps remain.
#### Step 10.3: Configure Email Verification to Handle Flows
**File:** `frontend/src/user_management/account/VerifyEmailByCode.jsx`
Replace the static `<Navigate>` component return with a `useEffect` hook that handles flow-based redirects.
Add the required imports:
```jsx
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { pathForFlow } from '../auth'
```
Instantiate navigate:
```jsx
const navigate = useNavigate()
```
Replace the `<Navigate>` return with a `useEffect` that redirects based on the response:
```jsx
useEffect(() => {
const content = response.content
if (!content) {
return
}
const flows = content.data?.flows
if (flows?.length) {
const pending = flows.find(flow => flow.is_pending)
if (pending) {
navigate(pathForFlow(pending), { replace: true })
return
}
}
if (content.status === 200) {
navigate('/account/email', { replace: true })
} else if (content.status === 401) {
navigate('/account/login', { replace: true })
}
}, [response.content, navigate])
```
This configuration ensures email verification redirects to the next pending flow step (e.g., passkey creation) or falls back to the appropriate default page.
---
### Step 11: Validate Authentication Flows with Automated Testing
Run the comprehensive authentication flow test suite to validate the entire integration. This step confirms all authentication flows work correctly end-to-end.
#### Step 11.1: Install Testing Dependencies
Activate the Django virtual environment and install Playwright for browser automation testing:
```bash
source venv/bin/activate
# Install pytest only if missing
python -c "import pytest" 2>/dev/null || pip install 'pytest>=7.4,<9.0'
# Install playwright only if missing
python -c "import playwright" 2>/dev/null || pip install playwright
# Install chromium only if Playwright hasn't installed it yet
playwright show-browsers | grep -q "chromium" \
|| playwright install chromium
```
#### Step 11.2: Check and Start Servers, Then Run the Test Suite
Before running tests, verify both servers are running and start them if needed.
**Check if backend is running on port 8000:**
```bash
lsof -i :8000
```
**If backend is not running, start it:**
Activate the virtual environment, and run the startup script in the background:
```bash
source venv/bin/activate && \
uvicorn backend.asgi:application \
--host 127.0.0.1 \
--port 8000 \
--ssl-keyfile ./certs/localhost+2-key.pem \
--ssl-certfile ./certs/localhost+2.pem
```
**Check if frontend is running on port 5173:**
```bash
lsof -i :5173
```
**If frontend is not running, start it:**
Start the development server in the background:
```bash
npm --prefix ./frontend run dev
```
**Wait for servers to be ready:**
Allow a few seconds for both servers to fully initialize before proceeding with tests.
**Execute the test suite:**
From the Django project root with the virtual environment activated:
Activate the virtual environment `source venv/bin/activate` and run the test script at: `scripts/test_auth_flows.py`
The test suite includes:
1. **test_01_signup** - User signup flow validation
2. **test_02_email_verification** - Email verification workflow
3. **test_03_password_login** - Password-based authentication
4. **test_04_logout** - Logout functionality
5. **test_05_code_login** - Passwordless code-based login
6. **test_06_password_reset** - Password reset workflow
**Prerequisites for testing:**
- Django backend running on `https://localhost:8000`
- React frontend running on `https://localhost:5173`
- Email backend configured to save emails to `sent_emails/` directory
- Clean database state (tests create unique users with timestamps)
**Test execution:**
- Tests run with visible browser (`headless=False`) for debugging
- Each test is independent and creates its own test user
- Tests clean up email files between runs
- Verbose output (`verbosity=2`) shows detailed test progress
**Note:** Tests run sequentially and may take several minutes to complete due to browser automation and wait times for email delivery.
---
### Step 12: Copy Styling Reference Guide
Read the styling reference guide from the skill's bundled resources and write it to the project root for later use.
The styling guide is located at `references/styling-guide.md` within this skill's directory. Read this file and write its contents to `react-allauth-styling-reference.md` in the project root.
This file lists all 35 authentication components that require styling and can be referenced by styling skills. Delete this file after styling is complete.
---
### Step 13: Stop Background Tasks
Terminate any background commands or servers started during the configuration process.

View File

@@ -0,0 +1,75 @@
# React-Allauth Components Requiring Styling
## Overview
This file lists all authentication components that require styling. These components are functional but use minimal styling from the django-allauth example repository. Apply consistent design using a styling skill (e.g., `apply-shadcn`).
## Components Requiring Styling
### Account Files (15 files)
1. `frontend/src/user_management/account/Login.jsx`
2. `frontend/src/user_management/account/RequestLoginCode.jsx`
3. `frontend/src/user_management/account/ConfirmLoginCode.jsx`
4. `frontend/src/user_management/account/Logout.jsx`
5. `frontend/src/user_management/account/Signup.jsx`
6. `frontend/src/user_management/account/ChangeEmail.jsx`
7. `frontend/src/user_management/account/VerifyEmail.jsx`
8. `frontend/src/user_management/account/VerifyEmailByCode.jsx`
9. `frontend/src/user_management/account/VerificationEmailSent.jsx`
10. `frontend/src/user_management/account/RequestPasswordReset.jsx`
11. `frontend/src/user_management/account/ConfirmPasswordResetCode.jsx`
12. `frontend/src/user_management/account/ChangePassword.jsx`
13. `frontend/src/user_management/account/ResetPassword.jsx`
14. `frontend/src/user_management/account/Reauthenticate.jsx`
### Social Account Files (3 files)
1. `frontend/src/user_management/socialaccount/ProviderSignup.jsx`
2. `frontend/src/user_management/socialaccount/ProviderCallback.jsx`
3. `frontend/src/user_management/socialaccount/ManageProviders.jsx`
### MFA Files (15 files)
1. `frontend/src/user_management/mfa/MFAOverview.jsx`
2. `frontend/src/user_management/mfa/ActivateTOTP.jsx`
3. `frontend/src/user_management/mfa/DeactivateTOTP.jsx`
4. `frontend/src/user_management/mfa/AuthenticateTOTP.jsx`
5. `frontend/src/user_management/mfa/ReauthenticateTOTP.jsx`
6. `frontend/src/user_management/mfa/RecoveryCodes.jsx`
7. `frontend/src/user_management/mfa/GenerateRecoveryCodes.jsx`
8. `frontend/src/user_management/mfa/AuthenticateRecoveryCodes.jsx`
9. `frontend/src/user_management/mfa/ReauthenticateRecoveryCodes.jsx`
10. `frontend/src/user_management/mfa/AddWebAuthn.jsx`
11. `frontend/src/user_management/mfa/ListWebAuthn.jsx`
12. `frontend/src/user_management/mfa/AuthenticateWebAuthn.jsx`
13. `frontend/src/user_management/mfa/ReauthenticateWebAuthn.jsx`
14. `frontend/src/user_management/mfa/SignupByPasskey.jsx`
15. `frontend/src/user_management/mfa/CreateSignupPasskey.jsx`
16. `frontend/src/user_management/mfa/Trust.jsx`
### Component Files (2 files)
1. `frontend/src/user_management/components/Button.jsx`
2. `frontend/src/user_management/mfa/WebAuthnLoginButton.jsx`
**Total:** 35 files requiring styling
## Button Component Duplication Issue
Two Button.jsx files exist in the project:
1. **`frontend/src/components/ui/button.jsx`** - shadcn/ui Button component with full styling variants
2. **`frontend/src/user_management/components/Button.jsx`** - Wrapper component that uses shadcn/ui Button
**Recommended approach:** Keep both files as they serve different purposes:
- **`frontend/src/components/ui/button.jsx`** - Core shadcn/ui component with styling system
- **`frontend/src/user_management/components/Button.jsx`** - Wrapper that ensures authentication components use consistent button styling
## Notes
- All components use React Router for navigation
- Components expect shadcn/ui components to be available via `@/components/ui/` imports
- The authentication context (`AuthContextProvider`) must wrap all components
- Components use the allauth API client from `user_management/lib/allauth.jsx`

View File

@@ -0,0 +1,353 @@
#!/usr/bin/env python3
"""
Professional test suite for Django-Allauth authentication flows.
Tests: Signup, Email Verification, Password Login, Logout, Code Login, Password Reset
"""
import os
import re
import time
import unittest
from pathlib import Path
from playwright.sync_api import sync_playwright
# Find project root by looking for Django project markers
# Works regardless of whether skill is installed at project or user level
def find_project_root():
"""Find Django project root by looking for manage.py or venv."""
cwd = Path.cwd()
# Search upwards for Django project markers
current = cwd
for _ in range(10): # Prevent infinite loop
# Look for Django project markers
if (current / 'manage.py').exists() and (current / 'venv').exists():
return current
if current.parent == current: # Reached filesystem root
break
current = current.parent
# Fallback: use current working directory
return cwd
PROJECT_ROOT = find_project_root()
EMAIL_DIR = PROJECT_ROOT / 'sent_emails'
class AuthenticationFlowTests(unittest.TestCase):
"""Test suite for complete authentication flows."""
@classmethod
def setUpClass(cls):
"""Set up test fixtures before running any tests."""
cls.password = "SecureTestPassword123!"
cls.new_password = "NewSecurePassword456!"
cls.playwright = None
cls.browser = None
cls.context = None
cls.page = None
def setUp(self):
"""Set up before each test."""
# Each test gets its own email to avoid conflicts
self.email = f"testuser_{int(time.time() * 1000)}@example.com"
time.sleep(0.1) # Ensure unique timestamps
self.clear_email_folder()
@staticmethod
def clear_email_folder():
"""Clear all emails from the email folder."""
if EMAIL_DIR.exists():
for f in EMAIL_DIR.iterdir():
f.unlink()
@staticmethod
def get_latest_email_content(wait_time=3):
"""Read the most recently created email file."""
# Wait for email file to be written
for _ in range(wait_time * 10): # Check every 100ms
if EMAIL_DIR.exists():
files = list(EMAIL_DIR.iterdir())
if files:
latest_file = max(files, key=lambda f: f.stat().st_ctime)
return latest_file.read_text()
time.sleep(0.1)
return None
@staticmethod
def extract_verification_code(email_content):
"""Extract the verification code from email."""
# Match 6-character alphanumeric code
pattern = r'^\s*([A-Z0-9]{6})\s*$'
match = re.search(pattern, email_content, re.MULTILINE)
return match.group(1) if match else None
@staticmethod
def extract_login_code(email_content):
"""Extract the login code from email."""
pattern = r'^\s*([A-Z0-9]{6})\s*$'
match = re.search(pattern, email_content, re.MULTILINE)
if match:
return match.group(1)
pattern = r'code:\s*([A-Z0-9]{6})'
match = re.search(pattern, email_content, re.IGNORECASE)
return match.group(1) if match else None
@staticmethod
def extract_password_reset_url(email_content):
"""Extract the password reset URL from email."""
pattern = r'https://localhost:5173/account/password/reset/key/([^\s\n]+)'
match = re.search(pattern, email_content)
return match.group(0) if match else None
def start_browser(self):
"""Start browser session."""
if not self.playwright:
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.context = self.browser.new_context(ignore_https_errors=True)
self.page = self.context.new_page()
def stop_browser(self):
"""Stop browser session."""
if self.page:
self.page.close()
if self.context:
self.context.close()
if self.browser:
self.browser.close()
if self.playwright:
self.playwright.stop()
self.page = None
self.context = None
self.browser = None
self.playwright = None
def test_01_signup(self):
"""Test user signup flow."""
self.start_browser()
try:
self.page.goto('https://localhost:5173/account/signup', wait_until='networkidle')
self.page.fill('[data-testid="signup-email"]', self.email)
self.page.fill('[data-testid="signup-password1"]', self.password)
self.page.fill('[data-testid="signup-password2"]', self.password)
self.page.click('[data-testid="signup-submit"]')
self.page.wait_for_url('**/account/verify-email', timeout=5000)
self.assertIn('verify-email', self.page.url, "Should redirect to verify-email page")
finally:
self.stop_browser()
def test_02_email_verification(self):
"""Test email verification flow."""
self.start_browser()
try:
# First signup
self.page.goto('https://localhost:5173/account/signup', wait_until='networkidle')
self.page.fill('[data-testid="signup-email"]', self.email)
self.page.fill('[data-testid="signup-password1"]', self.password)
self.page.fill('[data-testid="signup-password2"]', self.password)
self.page.click('[data-testid="signup-submit"]')
self.page.wait_for_url('**/account/verify-email', timeout=5000)
# Get verification email
email_content = self.get_latest_email_content()
self.assertIsNotNone(email_content, "Verification email should exist")
verification_code = self.extract_verification_code(email_content)
self.assertIsNotNone(verification_code, "Should extract verification code")
self.assertEqual(len(verification_code), 6, "Verification code should be 6 characters")
# Verify email with code
self.page.fill('[data-testid="verify-email-code-input"]', verification_code)
self.page.click('[data-testid="verify-email-code-submit"]')
self.page.wait_for_url('**/account/email', timeout=5000)
self.assertIn('email', self.page.url, "Should redirect to email management after verification")
finally:
self.stop_browser()
def test_03_password_login(self):
"""Test password-based login flow."""
self.start_browser()
try:
# Setup: signup and verify (user will be logged in after verification)
self._signup_and_verify()
# Logout first
self.page.goto('https://localhost:5173/account/logout', wait_until='networkidle')
time.sleep(1)
self.page.click('[data-testid="logout-submit"]')
time.sleep(2)
# Now login with password
self.page.goto('https://localhost:5173/account/login', wait_until='networkidle')
self.page.fill('[data-testid="login-email"]', self.email)
self.page.fill('[data-testid="login-password"]', self.password)
self.page.click('[data-testid="login-submit"]')
self.page.wait_for_url('https://localhost:5173/', timeout=5000)
# Verify logged in
logout_link = self.page.locator('a:has-text("Logout")')
self.assertGreater(logout_link.count(), 0, "Should see Logout link when logged in")
finally:
self.stop_browser()
def test_04_logout(self):
"""Test logout flow."""
self.start_browser()
try:
# Setup: login
self._login_user()
# Logout
self.page.goto('https://localhost:5173/account/logout', wait_until='networkidle')
time.sleep(1)
self.page.click('[data-testid="logout-submit"]')
self.page.wait_for_load_state('networkidle')
time.sleep(2)
# Verify logged out
self.page.goto('https://localhost:5173/', wait_until='networkidle')
time.sleep(1)
login_link = self.page.locator('a:has-text("Login")')
self.assertGreater(login_link.count(), 0, "Should see Login link when logged out")
finally:
self.stop_browser()
def test_05_code_login(self):
"""Test passwordless login with code flow."""
self.start_browser()
try:
# Setup: signup and verify (user will be logged in after verification)
self._signup_and_verify()
# Logout
self.page.goto('https://localhost:5173/account/logout', wait_until='networkidle')
time.sleep(1)
self.page.click('[data-testid="logout-submit"]')
time.sleep(2)
self.clear_email_folder()
# Request login code
self.page.goto('https://localhost:5173/account/login', wait_until='networkidle')
time.sleep(2)
self.page.click('a:has-text("Send me a sign-in code")')
self.page.wait_for_load_state('networkidle')
time.sleep(1)
self.page.fill('[data-testid="request-code-email"]', self.email)
self.page.click('[data-testid="request-code-submit"]')
self.page.wait_for_load_state('networkidle')
time.sleep(2)
# Get code from email
code_email = self.get_latest_email_content()
self.assertIsNotNone(code_email, "Login code email should exist")
login_code = self.extract_login_code(code_email)
self.assertIsNotNone(login_code, "Should extract login code")
self.assertEqual(len(login_code), 6, "Login code should be 6 characters")
# Enter code and login
self.page.fill('[data-testid="confirm-code-input"]', login_code)
self.page.click('[data-testid="confirm-code-submit"]')
self.page.wait_for_url('https://localhost:5173/', timeout=5000)
# Verify logged in
logout_link = self.page.locator('a:has-text("Logout")')
self.assertGreater(logout_link.count(), 0, "Should be logged in after code login")
finally:
self.stop_browser()
def test_06_password_reset(self):
"""Test password reset flow."""
self.start_browser()
try:
# Setup: signup and verify
self._signup_and_verify()
# Logout (should be at login page)
self.page.goto('https://localhost:5173/account/logout', wait_until='networkidle')
time.sleep(1)
if self.page.locator('[data-testid="logout-submit"]').count() > 0:
self.page.click('[data-testid="logout-submit"]')
time.sleep(2)
self.clear_email_folder()
# Request password reset
self.page.goto('https://localhost:5173/account/login', wait_until='networkidle')
time.sleep(1)
self.page.click('a:has-text("Forgot your password?")')
self.page.wait_for_load_state('networkidle')
time.sleep(1)
self.page.fill('[data-testid="password-reset-email"]', self.email)
self.page.click('[data-testid="password-reset-submit"]')
self.page.wait_for_load_state('networkidle')
time.sleep(2)
# Get reset email
reset_email = self.get_latest_email_content()
self.assertIsNotNone(reset_email, "Password reset email should exist")
reset_url = self.extract_password_reset_url(reset_email)
self.assertIsNotNone(reset_url, "Should extract password reset URL")
# Reset password
self.page.goto(reset_url)
self.page.wait_for_load_state('networkidle')
time.sleep(1)
self.page.fill('[data-testid="reset-password1"]', self.new_password)
self.page.fill('[data-testid="reset-password2"]', self.new_password)
self.page.click('[data-testid="reset-password-confirm"]')
self.page.wait_for_load_state('networkidle')
time.sleep(2)
# Password reset complete - now login with new password to verify it worked
# Navigate to login page
self.page.goto('https://localhost:5173/account/login', wait_until='networkidle')
time.sleep(1)
# Login with new password
self.page.fill('[data-testid="login-email"]', self.email)
self.page.fill('[data-testid="login-password"]', self.new_password)
self.page.click('[data-testid="login-submit"]')
self.page.wait_for_url('https://localhost:5173/', timeout=5000)
# Verify logged in with new password
logout_link = self.page.locator('a:has-text("Logout")')
self.assertGreater(logout_link.count(), 0, "Should be logged in with new password")
finally:
self.stop_browser()
# Helper methods
def _signup_and_verify(self):
"""Helper: signup and verify email."""
self.clear_email_folder()
self.page.goto('https://localhost:5173/account/signup', wait_until='networkidle')
self.page.fill('[data-testid="signup-email"]', self.email)
self.page.fill('[data-testid="signup-password1"]', self.password)
self.page.fill('[data-testid="signup-password2"]', self.password)
self.page.click('[data-testid="signup-submit"]')
self.page.wait_for_url('**/account/verify-email', timeout=5000)
email_content = self.get_latest_email_content()
verification_code = self.extract_verification_code(email_content)
self.page.fill('[data-testid="verify-email-code-input"]', verification_code)
self.page.click('[data-testid="verify-email-code-submit"]')
self.page.wait_for_url('**/account/email', timeout=5000)
# User is now logged in and on the email management page
def _login_user(self):
"""Helper: complete signup, verify, and login."""
self._signup_and_verify()
# User is already logged in after email verification
if __name__ == '__main__':
# Run tests with verbose output
unittest.main(verbosity=2)

View File

@@ -0,0 +1,37 @@
# React Setup Skill (Vite + Django Backend)
Spin up a fresh React app (Vite) that talks to a Django backend over HTTPS with correct CORS/CSRF handling, Axios defaults, and a basic router/layout scaffold.
## What This Skill Does
- Initializes a new Vite React project in `frontend/`.
- Configures `vite.config.js` for HTTPS dev using mkcert certs from `certs/`, port 5173, and proxying `/api` to `https://localhost:8000`.
- Adds CSRF service and Axios interceptors that inject `X-CSRFToken` for mutating requests.
- Sets up React Router layout (`Root`), navbar/footer, home page, and backend health check component that verifies CSRF + `/api/health/`.
- Provides a minimal API config file to centralize endpoints.
- Validates the build with `npm --prefix ./frontend run build`.
## Prerequisites
- Django backend running over HTTPS (see `django-setup` skill) with endpoints `/api/csrf/` and `/api/health/`.
- mkcert certificates stored in project `certs/` (key/cert filenames discovered in skill steps).
- Node.js 18+ and npm available.
## Setup Summary (see SKILL.md for exact commands)
1) **Create project**: `npm create vite@latest frontend -- --template react --yes`; then `npm --prefix ./frontend install react-router-dom axios`.
2) **Configure `vite.config.js`**: import `fs`/`path`; load mkcert key/cert from `certs/`; set `server.https`, `server.port=5173`, and proxy `/api``https://localhost:8000` with `secure:false`.
3) **API config** `src/config/api.js`: export `API_BASE_URL` (empty to use proxy) and `ENDPOINTS` with `CSRF: '/api/csrf/'`.
4) **CSRF service** `src/services/csrf.js`: fetch `/api/csrf/` once, read `csrftoken` cookie, cache/token helpers.
5) **Axios instance** `src/services/api.js`: `withCredentials:true`, JSON headers; request interceptor adds `X-CSRFToken` via `getCsrfToken()` for POST/PUT/PATCH/DELETE.
6) **UI scaffold**: navbar/footer components; `Root` layout with `Outlet`; `Home` page using `BackendStatus` component that pings CSRF then `/api/health/`.
7) **Routing**: `src/router/AppRoutes.jsx` exports `createAppRouter()` config; `src/router/index.jsx` wraps `RouterProvider`; `App.jsx` renders `<Router />`.
8) **Verify**: `npm --prefix ./frontend run build` to ensure config/imports succeed.
## Outputs/Artifacts
- Vite React app under `frontend/` with HTTPS dev server ready to hit Django.
- `vite.config.js` with mkcert HTTPS + API proxy.
- Axios + CSRF utilities wired for Django session auth.
- Minimal router/layout/pages demonstrating backend connectivity.
## Notes & Gotchas
- Make sure `certs/` exists and filenames match what mkcert generated; update `vite.config.js` accordingly.
- Backend must expose `/api/csrf/` to set the `csrftoken` cookie; otherwise Axios interceptor will fail.
- If you change backend host/port, update the proxy target in `vite.config.js` and any hardcoded `FRONTEND_URL` on the Django side.

268
skills/react-setup/SKILL.md Normal file
View File

@@ -0,0 +1,268 @@
---
name: react-setup
description: Use when initializing a new React frontend with Vite to connect to a Django backend over HTTPS. Sets up routing, CSRF protection, Axios config, and validates the build. Not for existing React projects.
allowed-tools: Bash, Write, Edit, Read, Glob, Grep, TodoWrite, Task
---
## Overview
Sets up a production-ready React + Vite frontend configured for Django backend integration with:
- HTTPS local development (using mkcert certificates)
- CSRF token handling for Django session auth
- Axios interceptors for automatic CSRF injection
- React Router with layout structure
- Production build validation
**When to use:** New React projects that need Django backend connectivity
**When NOT to use:** Existing React projects, non-Django backends, or projects not using session auth
## Prerequisites
- Django backend configured with HTTPS
- mkcert certificates in `/certs/` directory (use `mkcert-https-setup` skill)
- Node.js 18+ installed
---
Copy this checklist and track your progress:
- [ ] 1. Initialize React + Vite Project
- [ ] 2. Configure vite.config.js:
- [ ] 3. Create API Configuration
- [ ] 4. Create CSRF Service
- [ ] 5. Create Axios Configuration
- [ ] 6. Create Navbar and Footer Components
- [ ] 7. Create `src/layouts/Root.jsx`:
- [ ] 8. Create Page Components
- [ ] 9. Create `src/router/AppRoutes.jsx`
- [ ] 10. Create Router Wrapper
- [ ] 11. Update App.jsx
- [ ] 12. Verify Setup
---
1. Initialize React + Vite Project
- `npm create vite@latest frontend -- --template react --yes`
- `npm --prefix ./frontend install react-router-dom axios`
---
2. Configure vite.config.js:
1. List cert files in `certs/` to find actual filenames
2. Read existing `frontend/vite.config.js` (created by Vite)
3. Add imports: `fs`, `path`
4. Add server config:
- server.https: Load key/cert from `certs/` using found filenames
- server.port: 5173
- server.proxy: `/api``https://localhost:8000` (changeOrigin: true, secure: false)
---
3. Create API Configuration
src/config/api.js:
```javascript
export const API_BASE_URL = ''; // Empty string uses Vite proxy
export const ENDPOINTS = {
CSRF: '/api/csrf/',
// Add your API endpoints here as you build features
// Example: PRODUCTS: '/api/products/',
};
```
---
4. Create CSRF Service
src/services/csrf.js:
```javascript
import { ENDPOINTS } from '../config/api';
let csrfToken = null;
/**
* Fetches and caches the CSRF token from Django backend
* The token is stored in a cookie by Django after the first request
*/
export async function getCsrfToken() {
// Return cached token if available
if (csrfToken) {
return csrfToken;
}
try {
const response = await fetch(ENDPOINTS.CSRF, {
credentials: 'include',
headers: {
'Accept': 'application/json',
}
});
if (!response.ok) {
throw new Error(`Failed to fetch CSRF token: ${response.status}`);
}
// Django sets the token in a cookie after this request
const cookies = document.cookie.split(';');
const csrfCookie = cookies.find(cookie => cookie.trim().startsWith('csrftoken='));
if (!csrfCookie) {
throw new Error('CSRF token not found in cookies');
}
csrfToken = csrfCookie.split('=')[1].trim();
return csrfToken;
} catch (error) {
console.error('CSRF token fetch error:', error);
throw error;
}
}
/**
* Clears the cached CSRF token (useful for logout or token refresh)
*/
export function clearCsrfToken() {
csrfToken = null;
}
```
---
5. Create Axios Configuration
src/services/api.js:
```javascript
import axios from 'axios';
import { API_BASE_URL } from '../config/api';
import { getCsrfToken } from './csrf'; // ADD THIS
const axiosInstance = axios.create({
baseURL: API_BASE_URL,
withCredentials: true,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
// REQUEST INTERCEPTOR
axiosInstance.interceptors.request.use(
async (config) => {
if (['post', 'put', 'patch', 'delete'].includes(config.method.toLowerCase())) {
const csrfToken = await getCsrfToken();
config.headers['X-CSRFToken'] = csrfToken;
}
return config;
}
);
// Response interceptor
axiosInstance.interceptors.response.use(
response => response,
error => {
console.error('API request failed:', error);
return Promise.reject(error);
}
);
export default axiosInstance;
```
---
6. Create Navbar and Footer Components
Create `src/components/Navbar.jsx`:
```javascript
export default function Navbar() {
return (
<nav>
<h1>My App</h1>
</nav>
);
}
```
Create `src/components/Footer.jsx`:
```javascript
export default function Footer() {
return (
<footer>
<p>&copy; {new Date().getFullYear()} My App. All rights reserved.</p>
</footer>
);
}
```
---
7. Create `src/layouts/Root.jsx`:
```javascript
import { Outlet } from 'react-router-dom';
import Navbar from '../components/Navbar';
import Footer from '../components/Footer';
export default function Root() {
return (
<div>
<Navbar />
<main>
<Outlet />
</main>
<Footer />
</div>
);
}
```
---
8. Create Page Components
Create `src/components/BackendStatus.jsx`:
1. Import axios from `../services/api`, useState, useEffect
2. Initialize state: `status = "checking..."`, `error = null`
3. useEffect hook (runs on mount):
- First: `axios.get('/api/csrf/')` to initialize cookies
- Second: `axios.get('/api/health/')` using same axios instance
- Success path: update status with backend message
- Error path: set error state, display "Backend unreachable"
4. Component is presentational only (no routing/layout logic)
Create `src/pages/Home.jsx`:
1. Render `<BackendStatus />`
2. Add heading + text explaining the backend connectivity check
---
9. Create `src/router/AppRoutes.jsx`:
1. Export `createAppRouter()` function
2. Returns route config array: Root layout at "/" with Home page as nested "/" child route
3. Imports: `Root` from `../layouts/Root`, `Home` from `../pages/Home`
---
10. Create `src/router/index.jsx`:
1. Export default `AppRouter` component
2. Create browser router from `createAppRouter()` config
3. Return `<RouterProvider router={router} />`
4. Imports: `createBrowserRouter`, `RouterProvider` from react-router-dom, `createAppRouter` from `./AppRoutes`
---
11. Update `src/App.jsx`:
- Remove: All useState, demo imports (reactLogo, viteLogo, App.css), counter UI
- Add imports: `Router` from `./router`
- Render: `<Router />`
---
12. Verify Setup
Run `npm --prefix ./frontend run build` to validate imports, dependencies, and syntax
**Common issues:**
- Missing certs: Check `/certs/` directory exists with .pem files
- Module not found: Verify all imports use correct paths
- CSRF errors: Ensure Django backend is running at `https://localhost:8000`

View File

@@ -0,0 +1,41 @@
# Tailwind Setup Skill (Vite + shadcn/ui)
Add Tailwind CSS, shadcn/ui, dark-mode theme tokens, and aliases to a React/Vite frontend that talks to a Django backend.
## What This Skill Does
- Installs Tailwind (+ Vite plugin) and core shadcn/ui deps (`class-variance-authority`, `clsx`, `tailwind-merge`, `lucide-react`).
- Updates `vite.config.js` to run `tailwindcss()` alongside React and adds `@` alias → `./src`.
- Replaces `src/index.css` with Tailwind entry, then appends theme tokens via `scripts/apply-theme.sh` (uses `assets/tailwind-theme.css`) for dark/light palettes.
- Sets up shadcn/ui scaffolding: `components.json`, `jsconfig.json` aliases, and utility `src/lib/utils.js`.
- Enables class-based dark mode in `tailwind.config.js`.
- Adds `ThemeContext` & `ThemeToggle` components and wraps `App` with `ThemeProvider`.
- Installs shadcn/ui components (card, field, input, button, table, navigation-menu, label, separator, alert) via CLI.
- Verifies build with `npm --prefix ./frontend run build`.
## Prerequisites
- React + Vite frontend in `frontend/`.
- Django backend already set up (used only for proxy alignment).
- Node.js 18+ and npm; mkcert HTTPS recommended.
## Setup Summary (see SKILL.md for exact edits)
1) **Deps**: `npm --prefix ./frontend install tailwindcss @tailwindcss/vite class-variance-authority clsx tailwind-merge lucide-react`.
2) **Vite config**: import `path`, `tailwindcss`; add plugin; add `resolve.alias` `{ '@': path.resolve(__dirname, './src') }`.
3) **CSS entry**: set `src/index.css` to `@import "tailwindcss";`.
4) **Theme tokens**: run `bash .claude/skills/tailwind-setup/scripts/apply-theme.sh frontend` (appends tokens to `src/index.css`).
5) **shadcn scaffolding**: create `components.json`, `jsconfig.json`, `src/lib/utils.js`.
6) **Tailwind config**: `darkMode: 'class'`, content globs for `./index.html` and `./src/**/*.{js,jsx}`.
7) **ThemeProvider + toggle**: add `src/contexts/ThemeContext.jsx`, `src/components/ThemeToggle.jsx`; wrap `<Router />` in `App.jsx`; drop toggle into navbar.
8) **shadcn components**: run `npx --prefix ./frontend shadcn@latest add ...` for card/field/input/button/table/navigation-menu/label/separator/alert.
9) **Build check**: `npm --prefix ./frontend run build`.
## Outputs/Artifacts
- Tailwind + shadcn tokens in `src/index.css`.
- `tailwind.config.js`, `components.json`, `jsconfig.json`, `src/lib/utils.js`.
- Theme context/toggle components added and App wrapped.
- Installed shadcn/ui primitives ready for use.
## Notes & Gotchas
- Run theme script from project root and pass `frontend` path arg.
- Ensure Vite aliases in `vite.config.js` and `jsconfig.json` match.
- If you already have CSS content, back it up before replacing with Tailwind import (tokens are appended by the script).
- Add additional content globs to `tailwind.config.js` if you place components elsewhere.

View File

@@ -0,0 +1,352 @@
---
name: tailwind-setup
description: Configure Tailwind CSS and shadcn/ui for React frontends with Django backends, including dark mode support and theme tokens. This skill should be used when setting up a new React project or adding Tailwind to an existing one.
allowed-tools: Bash, Write, Edit, Read, Glob, Grep, TodoWrite, mcp__shadcn__get_project_registries, mcp__shadcn__search_items_in_registries, mcp__shadcn__view_items_in_registries, mcp__shadcn__get_item_examples_from_registries, mcp__shadcn__get_add_command_for_items, mcp__shadcn__get_audit_checklist
---
## Purpose
Configure Tailwind CSS with shadcn/ui for React frontends connecting to Django backends. This setup includes dark mode support, theme tokens, and shadcn/ui component integration. The configuration enables automatic dark mode switching and provides a foundation for building consistent, themeable user interfaces.
## Setup Process Overview
Follow these steps in order:
1. Install Dependencies
2. Configure Vite for Django Backend
3. Setup Tailwind in CSS
4. Apply Base Theme (Required for dark mode support)
5. Setup shadcn/ui
6. Implement Dark Mode with Toggle
7. Verify Setup and Check for Errors
---
## Step 1: Install Dependencies
Install Tailwind CSS and the Vite plugin:
```bash
npm --prefix ./frontend tailwindcss @tailwindcss/vite
```
## Step 2: Configure Vite for Django Backend
Configure `vite.config.js` to enable Tailwind and path aliases:
1. Read existing `vite.config.js`
2. Add the required imports at the top (keep the existing React import):
```javascript
import path from 'node:path'
import tailwindcss from '@tailwindcss/vite'
```
3. Update the plugins array so Tailwind runs alongside React:
```javascript
plugins: [
react(),
tailwindcss(),
]
```
4. Define the alias block in the same file so `@/` resolves to `src` (this relies on the `path` import above):
```javascript
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
}
```
## Step 3: Setup Tailwind in CSS
Configure the main CSS file to import Tailwind:
1. Read existing `src/index.css`
2. Replace the entire contents with the Tailwind import:
```css
@import "tailwindcss";
```
## Step 4: Apply Base Theme
Apply the base theme by running the bundled script from the project root directory at: `scripts/apply-theme.sh`
Apply the base theme by running the script from the skill's bundled resources at:`scripts/apply-theme.sh` within this skill's directory.
The script requires requires the frontend directory path (relative to project
root) as an argument.
3. **Run the theme script from project root**:
```bash
bash <path-to-skill>/scripts/apply-theme.sh frontend
```
The script appends shadcn/ui's design tokens (from `assets/tailwind-theme.css`, in the skill's bundled resources) to `src/index.css`, adding support for typography, colors, and automatic dark mode.
## Step 5: Setup shadcn/ui
### 5a. Install shadcn/ui Dependencies
Install the required packages for shadcn/ui component functionality:
```bash
npm --prefix ./frontend install class-variance-authority clsx tailwind-merge lucide-react
```
### 5b. Create jsconfig.json for Path Aliases
Create `jsconfig.json` in the frontend root directory:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
### 5c. Create Utility Helper Function
Create `src/lib/utils.js`:
```javascript
import { clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs) {
return twMerge(clsx(inputs))
}
```
### 5d. Create components.json Configuration
Create `components.json` in the frontend root directory:
```json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": false,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
```
### 5e. Install shadcn/ui Components
**PREREQUISITE:** Before installing components, verify their availability and review usage patterns using the shadcn MCP server. This ensures compatibility with the current registry and helps understand proper implementation patterns.
**MCP Verification:**
Use the shadcn MCP tools to search for each component and confirm it exists in the registry:
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="card"`
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="button"`
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="navigation-menu"`
- `mcp__shadcn__search_items_in_registries` with `registries=["@shadcn"]` and `query="alert"`
**Install Required Components:**
Once verified, install the components using the shadcn CLI:
```bash
npx --prefix ./frontend shadcn@latest add card
npx --prefix ./frontend shadcn@latest add field
npx --prefix ./frontend shadcn@latest add input
npx --prefix ./frontend shadcn@latest add button
npx --prefix ./frontend shadcn@latest add table
npx --prefix ./frontend shadcn@latest add navigation-menu
npx --prefix ./frontend shadcn@latest add label
npx --prefix ./frontend shadcn@latest add separator
npx --prefix ./frontend shadcn@latest add alert
```
## Step 6: Implement Dark Mode with Toggle
### 6a. Configure Tailwind for Class-based Dark Mode
Create or update `tailwind.config.js` in the frontend root directory, to enable class-based dark mode:
```js
/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class',
content: [
"./index.html",
"./src/**/*.{js,jsx}",
],
}
```
### 6b. Create Theme Context
Create `src/contexts/ThemeContext.jsx`:
```js
import { createContext, useContext, useEffect, useState } from "react";
const ThemeContext = createContext({
theme: "system",
setTheme: () => null,
});
export function ThemeProvider({ children, defaultTheme = "system", storageKey = "theme" }) {
const [theme, setTheme] = useState(() => {
return localStorage.getItem(storageKey) || defaultTheme;
});
useEffect(() => {
const root = document.documentElement;
root.classList.remove("dark");
if (theme === "system") {
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
if (systemTheme) {
root.classList.add("dark");
}
return;
}
if (theme === "dark") {
root.classList.add("dark");
}
}, [theme]);
const value = {
theme,
setTheme: (newTheme) => {
localStorage.setItem(storageKey, newTheme);
setTheme(newTheme);
},
};
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error("useTheme must be used within a ThemeProvider");
}
return context;
}
```
### 6c. Create Theme Toggle Button Component
Create `src/components/ThemeToggle.jsx`:
```js
import { Moon, Sun } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useTheme } from "@/contexts/ThemeContext";
export default function ThemeToggle() {
const { theme, setTheme } = useTheme();
const toggleTheme = () => {
// If currently system or light, switch to dark
// If currently dark, switch to light
if (theme === "dark") {
setTheme("light");
} else {
setTheme("dark");
}
};
return (
<Button
variant="ghost"
size="icon"
onClick={toggleTheme}
aria-label="Toggle theme"
className="cursor-pointer"
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
</Button>
);
}
```
### 6d. Wrap App with ThemeProvider
Update `src/App.jsx` to include the ThemeProvider:
```js
import Router from "./router";
import { ThemeProvider } from "@/contexts/ThemeContext";
function App() {
return (
<ThemeProvider defaultTheme="system" storageKey="theme">
<Router />
</ThemeProvider>
);
}
export default App;
```
### 6e. Add Theme Toggle to Navbar
Integrate the ThemeToggle component into the navigation bar:
1. **Locate the navbar component**: Find the main navigation component (commonly in `src/components/Navbar.jsx` or similar)
2. **Import the ThemeToggle component**:
```js
import ThemeToggle from "@/components/ThemeToggle";
```
3. **Add the toggle to the navbar**: Place the `<ThemeToggle />` component in an appropriate location within the navbar, typically in the right section alongside other navigation items:
```jsx
<nav className="flex items-center justify-between p-4">
<div>{/* Logo and left-side nav items */}</div>
<div className="flex items-center gap-4">
{/* Other right-side nav items */}
<ThemeToggle />
</div>
</nav>
```
## Step 7: Run Build to Check for Compilation Errors
Build the project to verify there are no compilation errors:
```bash
npm --prefix ./frontend run build
```
If the build succeeds, the setup is complete. If there are errors:
- Check for missing imports or incorrect file paths
- Verify all components were installed correctly
- Ensure `jsconfig.json` path aliases match `vite.config.js` aliases
- Confirm `tailwind.config.js` content paths include all component files
## Setup Complete
The Tailwind CSS and shadcn/ui setup is now complete. The project includes:
- Tailwind CSS with Vite integration
- shadcn/ui design tokens and theme variables
- Dark mode support with class-based switching
- Path aliases configured for clean imports (`@/components`, `@/lib`, etc.)
- Core shadcn/ui components installed and ready to use

View File

@@ -0,0 +1,97 @@
/* Base Theme Configuration */
@layer base {
:root {
--background: oklch(1.0000 0 0);
--foreground: oklch(0.2686 0 0);
--card: oklch(1.0000 0 0);
--card-foreground: oklch(0.2686 0 0);
--popover: oklch(1.0000 0 0);
--popover-foreground: oklch(0.2686 0 0);
--primary: oklch(0.7686 0.1647 70.0804);
--primary-foreground: oklch(0 0 0);
--secondary: oklch(0.9670 0.0029 264.5419);
--secondary-foreground: oklch(0.4461 0.0263 256.8018);
--muted: oklch(0.9846 0.0017 247.8389);
--muted-foreground: oklch(0.5510 0.0234 264.3637);
--accent: oklch(0.9869 0.0214 95.2774);
--accent-foreground: oklch(0.4732 0.1247 46.2007);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1.0000 0 0);
--border: oklch(0.9276 0.0058 264.5313);
--input: oklch(0.9276 0.0058 264.5313);
--ring: oklch(0.7686 0.1647 70.0804);
--chart-1: oklch(0.7686 0.1647 70.0804);
--chart-2: oklch(0.6658 0.1574 58.3183);
--chart-3: oklch(0.5553 0.1455 48.9975);
--chart-4: oklch(0.4732 0.1247 46.2007);
--chart-5: oklch(0.4137 0.1054 45.9038);
--radius: 0.375rem;
}
.dark {
--background: oklch(0.2046 0 0);
--foreground: oklch(0.9219 0 0);
--card: oklch(0.2686 0 0);
--card-foreground: oklch(0.9219 0 0);
--popover: oklch(0.2686 0 0);
--popover-foreground: oklch(0.9219 0 0);
--primary: oklch(0.7686 0.1647 70.0804);
--primary-foreground: oklch(0 0 0);
--secondary: oklch(0.2686 0 0);
--secondary-foreground: oklch(0.9219 0 0);
--muted: oklch(0.2393 0 0);
--muted-foreground: oklch(0.7155 0 0);
--accent: oklch(0.4732 0.1247 46.2007);
--accent-foreground: oklch(0.9243 0.1151 95.7459);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1.0000 0 0);
--border: oklch(0.3715 0 0);
--input: oklch(0.3715 0 0);
--ring: oklch(0.7686 0.1647 70.0804);
--chart-1: oklch(0.8369 0.1644 84.4286);
--chart-2: oklch(0.6658 0.1574 58.3183);
--chart-3: oklch(0.4732 0.1247 46.2007);
--chart-4: oklch(0.5553 0.1455 48.9975);
--chart-5: oklch(0.4732 0.1247 46.2007);
}
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}

View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Script to apply Tailwind theme to index.css
# Usage: bash apply-theme.sh <frontend-directory>
# Example: bash apply-theme.sh frontend
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
THEME_FILE="$SCRIPT_DIR/../assets/tailwind-theme.css"
# Check if frontend directory argument provided
if [ -z "$1" ]; then
echo "Error: Please provide the frontend directory path"
echo "Usage: bash apply-theme.sh <frontend-directory>"
echo "Example: bash apply-theme.sh frontend"
exit 1
fi
TARGET_DIR="$1"
TARGET_FILE="$TARGET_DIR/src/index.css"
# Check if target file exists
if [ ! -f "$TARGET_FILE" ]; then
echo "Error: $TARGET_FILE not found."
echo "Make sure '$TARGET_DIR' is the correct frontend directory path."
exit 1
fi
# Check if theme file exists
if [ ! -f "$THEME_FILE" ]; then
echo "Error: Theme file not found at $THEME_FILE"
exit 1
fi
# Check if theme already applied
if grep -q "Base Theme Configuration" "$TARGET_FILE"; then
echo "Theme already appears to be applied to $TARGET_FILE"
echo "Skipping to avoid duplication."
exit 0
fi
# Append theme to index.css
echo "" >> "$TARGET_FILE"
cat "$THEME_FILE" >> "$TARGET_FILE"
echo "✓ Tailwind theme successfully applied to $TARGET_FILE"