feat: add workflows for CMS, E-commerce, Blog + backend-developer agent + prompt-engineering rules

This commit is contained in:
¨NW¨
2026-04-05 01:19:09 +01:00
parent 1f96aec2b6
commit 23eb60762c
7 changed files with 6266 additions and 568 deletions

View File

@@ -0,0 +1,268 @@
---
description: Backend specialist for Node.js, Express, APIs, and database integration
mode: subagent
model: ollama-cloud/deepseek-v3.2
color: "#10B981"
permission:
read: allow
edit: allow
write: allow
bash: allow
glob: allow
grep: allow
task:
"*": deny
---
# Kilo Code: Backend Developer
## Role Definition
You are **Backend Developer** — the server-side specialist. Your personality is architectural, security-conscious, and performance-focused. You design robust APIs, manage databases, and ensure backend reliability.
## When to Use
Invoke this mode when:
- Building Node.js/Express APIs
- Designing database schemas
- Implementing authentication systems
- Creating REST/GraphQL endpoints
- Setting up middleware and security
- Database migrations and queries
## Short Description
Backend specialist for Node.js, Express, APIs, and database integration.
## Behavior Guidelines
1. **Security First** — Always validate input, sanitize output, protect against injection
2. **RESTful Design** — Follow REST principles for API design
3. **Error Handling** — Catch all errors, return proper HTTP status codes
4. **Database Best Practices** — Use migrations, proper indexing, query optimization
5. **Modular Architecture** — Separate concerns: routes, controllers, services, models
## Tech Stack
| Layer | Technologies |
|-------|-------------|
| Runtime | Node.js 20.x LTS |
| Framework | Express.js 4.x |
| Database | SQLite (better-sqlite3), PostgreSQL |
| ORM | Knex.js, Prisma |
| Auth | JWT, bcrypt, passport |
| Validation | Joi, Zod |
| Testing | Jest, Supertest |
## Output Format
```markdown
## Backend Implementation: [Feature]
### API Endpoints Created
| Method | Path | Description |
|--------|------|-------------|
| GET | /api/resource | List resources |
| POST | /api/resource | Create resource |
| PUT | /api/resource/:id | Update resource |
| DELETE | /api/resource/:id | Delete resource |
### Database Changes
- Table: `resources`
- Columns: id, name, created_at, updated_at
- Indexes: idx_resources_name
### Files Created
- `src/routes/api/resources.js` - API routes
- `src/controllers/resources.js` - Controllers
- `src/services/resources.js` - Business logic
- `src/models/Resource.js` - Data model
- `src/db/migrations/001_resources.js` - Migration
### Security
- ✅ Input validation (Joi schema)
- ✅ SQL injection protection (parameterized queries)
- ✅ XSS protection (helmet middleware)
- ✅ Rate limiting (express-rate-limit)
---
Status: implemented
@CodeSkeptic ready for review
```
## Database Patterns
### Migration Template
```javascript
// src/db/migrations/001_users.js
exports.up = function(knex) {
return knex.schema.createTable('users', table => {
table.increments('id').primary();
table.string('email').unique().notNullable();
table.string('password_hash').notNullable();
table.string('name').notNullable();
table.enum('role', ['admin', 'user']).defaultTo('user');
table.timestamps(true, true);
table.index('email');
});
};
exports.down = function(knex) {
return knex.schema.dropTable('users');
};
```
### Model Template
```javascript
// src/models/User.js
class User {
static create(data) {
const stmt = db.prepare(`
INSERT INTO users (email, password_hash, name, role)
VALUES (?, ?, ?, ?)
`);
return stmt.run(data.email, data.passwordHash, data.name, data.role);
}
static findByEmail(email) {
const stmt = db.prepare('SELECT * FROM users WHERE email = ?');
return stmt.get(email);
}
static findById(id) {
const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
return stmt.get(id);
}
}
```
### Route Template
```javascript
// src/routes/api/users.js
const router = require('express').Router();
const { body, validationResult } = require('express-validator');
const auth = require('../../middleware/auth');
const userService = require('../../services/users');
// GET /api/users - List users
router.get('/', auth.requireAdmin, async (req, res, next) => {
try {
const users = await userService.findAll();
res.json(users);
} catch (error) {
next(error);
}
});
// POST /api/users - Create user
router.post('/',
[
body('email').isEmail(),
body('name').notEmpty(),
body('password').isLength({ min: 8 })
],
async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const user = await userService.create(req.body);
res.status(201).json(user);
} catch (error) {
next(error);
}
}
);
module.exports = router;
```
## Authentication Patterns
### JWT Middleware
```javascript
// src/middleware/auth.js
const jwt = require('jsonwebtoken');
const JWT_SECRET = process.env.JWT_SECRET || 'secret';
function requireAuth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = jwt.verify(token, JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
}
function requireAdmin(req, res, next) {
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Admin access required' });
}
next();
}
module.exports = { requireAuth, requireAdmin };
```
## Error Handling
```javascript
// src/middleware/errorHandler.js
function errorHandler(err, req, res, next) {
console.error(err.stack);
const status = err.status || 500;
const message = err.message || 'Internal Server Error';
res.status(status).json({
error: message,
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
});
}
module.exports = errorHandler;
```
## Prohibited Actions
- DO NOT store passwords in plain text
- DO NOT skip input validation
- DO NOT expose stack traces in production
- DO NOT use synchronous operations in request handlers
- DO NOT hardcode secrets or credentials
## Handoff Protocol
After implementation:
1. Verify all endpoints work
2. Check security headers
3. Test error handling
4. Create database migration
5. Tag `@CodeSkeptic` for review
## Gitea Commenting (MANDATORY)
**You MUST post a comment to the Gitea issue after completing your work.**
Post a comment with:
1. ✅ Success: What was done, files changed, duration
2. ❌ Error: What failed, why, and blocker
3. ❓ Question: Clarification needed with options
Use the `post_comment` function from `.kilo/skills/gitea-commenting/SKILL.md`.
**NO EXCEPTIONS** - Always comment to Gitea.

1195
.kilo/commands/blog.md Normal file

File diff suppressed because it is too large Load Diff

1270
.kilo/commands/commerce.md Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,328 @@
# Prompt Engineering Rules
Guidelines for crafting effective prompts for AI agents.
## General Principles
### Be Clear and Specific
- Clearly state what you want the agent to do
- Avoid ambiguity and vague instructions
- Include specific file paths, function names, and line numbers when relevant
**Bad:** Fix the code.
**Good:** Fix the bug in the `calculateTotal` function that causes it to return incorrect results when cart is empty.
### Provide Context
- Use context mentions (`@/path/to/file`) to refer to specific files
- Include relevant code snippets or error messages
- Reference related issues or previous changes
**Good:** `@/src/utils.ts` Refactor the `calculateTotal` function to use async/await instead of callbacks.
### Break Down Tasks
- Divide complex tasks into smaller, well-defined steps
- Use numbered lists for multi-step instructions
- Specify the order of operations
**Good:**
```
1. First, analyze the current implementation
2. Identify performance bottlenecks
3. Refactor the main loop to use caching
4. Add unit tests for the new implementation
5. Verify the changes don't break existing tests
```
### Give Examples
- If you have a specific coding style in mind, provide examples
- Show the expected input/output format
- Include code snippets that demonstrate the pattern
### Specify Output Format
- If you need output in a particular format, specify it
- Common formats: JSON, Markdown, TypeScript interfaces
- Include example structure when necessary
## Thinking vs. Doing
Guide agents through a "think-then-do" process:
### Analyze Phase
Ask the agent to analyze the current code, identify problems, or plan the approach.
**Prompt Pattern:**
```
Analyze the current implementation of [feature].
Identify:
- Potential issues
- Areas for improvement
- Security vulnerabilities
```
### Plan Phase
Have the agent outline the steps it will take to complete the task.
**Prompt Pattern:**
```
Before making any changes, provide a plan:
1. What files will be modified
2. What functions will be added/changed
3. What dependencies are needed
4. What tests should be written
```
### Execute Phase
Instruct the agent to implement the plan, one step at a time.
**Prompt Pattern:**
```
Now implement the plan:
1. Start with [first step]
2. Then [second step]
...
```
### Review Phase
Carefully review the results of each step before proceeding.
**Prompt Pattern:**
```
Review the changes:
- Do they meet the requirements?
- Are there any side effects?
- Do the tests pass?
```
## Custom Instructions
### Global Custom Instructions
Apply to all agents and modes. Place in `.kilo/rules/global.md` or `AGENTS.md`.
**Examples:**
- Enforce coding style guidelines
- Specify preferred libraries
- Define project-specific conventions
### Mode-Specific Custom Instructions
Apply only to specific agents. Place in `.kilo/agents/[agent].md`.
**Examples:**
- Lead Developer: "Always write tests before code (TDD)"
- Code Skeptic: "Check for security vulnerabilities first"
- Frontend Developer: "Use Tailwind CSS for all styling"
## Handling Ambiguity
### When Request is Unclear
The agent should:
1. **Ask clarifying questions** using the `question` tool
2. **Not make assumptions** without user confirmation
3. **Provide options** for the user to choose from
**Example:**
```
I need clarification:
- Option A: Implement as a new module
- Option B: Add to existing service
- Option C: Create a separate microservice
```
### Providing Multiple Options
When presenting choices:
- Use clear, concise labels
- Provide descriptions for each option
- Recommend a default choice
- Allow custom input
## Providing Feedback
### Rejecting Actions
When the agent proposes an incorrect action:
1. Explain *why* the action is wrong
2. Provide the correct approach
3. Give an example if helpful
**Example:**
```
This approach won't work because [reason].
Instead, use [correct approach].
Here's an example: [code snippet]
```
### Rewording Requests
If initial prompt doesn't produce desired results:
1. Be more specific about requirements
2. Add constraints or boundaries
3. Provide examples of expected output
4. Break into smaller sub-tasks
## Prompt Patterns
### Feature Request Pattern
```markdown
## Feature: [Feature Name]
### Requirements
1. [Requirement 1]
2. [Requirement 2]
### Acceptance Criteria
- [ ] [Criterion 1]
- [ ] [Criterion 2]
### Files to Modify
- `path/to/file1.ts`
- `path/to/file2.ts`
### Constraints
- Use [library/framework]
- Follow [pattern/style]
- Must be backward compatible
```
### Bug Fix Pattern
```markdown
## Bug: [Bug Description]
### Current Behavior
[What's happening now]
### Expected Behavior
[What should happen]
### Steps to Reproduce
1. [Step 1]
2. [Step 2]
### Files Involved
- `path/to/file.ts` (line X)
### Error Message
```
[Stack trace or error message]
```
```
### Refactoring Pattern
```markdown
## Refactor: [What to Refactor]
### Current Implementation
[Brief description or code snippet]
### Target Implementation
[What it should become]
### Reason
[Why this refactoring is needed]
### Files to Update
- [File list]
### Requirements
- Maintain existing functionality
- Keep tests passing
- Update documentation
```
## Examples
### Good Prompts
**Feature Implementation:**
> `@/src/components/Button.tsx` Refactor the `Button` component to support three variants: primary, secondary, and danger. Use the design tokens from `@/src/styles/tokens.ts`.
**Bug Fix:**
> `@problems` Fix the TypeError in `calculateTotal` when the cart is empty. The function should return 0 for empty arrays.
**Architecture:**
> Create a new service for handling user notifications. Follow the pattern in `@/src/services/EmailService.ts`. The service should support email, SMS, and push notifications.
### Bad Prompts
**Too Vague:**
> Fix the button. (What's wrong with it?)
**No Context:**
> Write some Python code. (What should it do?)
**Too Broad:**
> Fix everything. (What is "everything"?)
**No Constraints:**
> Create a new feature. (What feature? For what?)
## Prompt Anti-Patterns
### Avoid These Patterns
1. **Kitchen Sink Prompts**
- Asking for too many things at once
- Better: Break into multiple focused prompts
2. **Missing Constraints**
- Not specifying required libraries or patterns
- Better: Always mention relevant constraints
3. **Assuming Knowledge**
- Expecting the agent to know project context
- Better: Provide `@file` references
4. **Ignoring Output**
- Not reviewing agent's changes
- Better: Always review and provide feedback
5. **No Iteration**
- Accepting first result without refinement
- Better: Iterate on prompts for better results
## Context Mentions
Use context mentions to provide specific file references:
| Mention | Description |
|---------|-------------|
| `@file.js` | Reference a specific file |
| `@/src/utils/` | Reference a directory |
| `@problems` | Reference all errors in the file |
| `@git` | Reference git history |
| `@terminal` | Reference terminal output |
## Iterative Prompting
When initial results aren't perfect:
1. **Identify Issues:** What's wrong with the current output?
2. **Clarify Requirements:** Add more specific instructions
3. **Provide Examples:** Show the expected format or pattern
4. **Break Down:** Split complex tasks into smaller ones
5. **Refine:** Adjust constraints or add context
## Verification Checklist
After receiving agent output:
- [ ] Does it meet all stated requirements?
- [ ] Are there any syntax errors?
- [ ] Does it follow project conventions?
- [ ] Are edge cases handled?
- [ ] Is it backward compatible?
- [ ] Are tests included/updated?
- [ ] Is documentation updated?

489
.kilo/skills/blog/SKILL.md Normal file
View File

@@ -0,0 +1,489 @@
---
name: blog
description: Blog/CMS domain knowledge - posts, categories, tags, comments, authors, SEO
---
# Blog Skill
## Purpose
Provides domain knowledge for building blog and content management systems: posts, categories, tags, comments, authors, SEO optimization.
## Capabilities
### Content Management
- Post CRUD operations
- Draft/Published/Archived states
- Content scheduling
- Rich text editing
- Media embedding
### Organization
- Categories (hierarchical)
- Tags (flat)
- Author assignment
- Content series
### Comments
- Comment moderation
- Threaded comments
- Spam filtering
- Social login comments
### SEO
- Meta tags
- Open Graph
- Structured data (Schema.org)
- Sitemap generation
- RSS feeds
### Analytics
- View counts
- Reading time estimation
- Popular posts
- Related posts
## Database Schema
### Posts
```sql
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
excerpt TEXT,
content TEXT NOT NULL,
featured_image TEXT,
author_id INTEGER NOT NULL,
category_id INTEGER,
status TEXT DEFAULT 'draft', -- 'draft', 'published', 'archived'
published_at DATETIME,
meta_title TEXT,
meta_description TEXT,
canonical_url TEXT,
reading_time INTEGER, -- minutes
view_count INTEGER DEFAULT 0,
allow_comments BOOLEAN DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES users(id),
FOREIGN KEY (category_id) REFERENCES categories(id)
);
CREATE INDEX idx_posts_slug ON posts(slug);
CREATE INDEX idx_posts_status ON posts(status);
CREATE INDEX idx_posts_published ON posts(published_at);
CREATE INDEX idx_posts_author ON posts(author_id);
CREATE INDEX idx_posts_category ON posts(category_id);
```
### Categories
```sql
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
description TEXT,
parent_id INTEGER,
image_url TEXT,
meta_title TEXT,
meta_description TEXT,
sort_order INTEGER DEFAULT 0,
FOREIGN KEY (parent_id) REFERENCES categories(id)
);
CREATE INDEX idx_categories_parent ON categories(parent_id);
```
### Tags
```sql
CREATE TABLE tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
description TEXT
);
CREATE TABLE post_tags (
post_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
PRIMARY KEY (post_id, tag_id),
FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
);
CREATE INDEX idx_post_tags_post ON post_tags(post_id);
CREATE INDEX idx_post_tags_tag ON post_tags(tag_id);
```
### Comments
```sql
CREATE TABLE comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_id INTEGER NOT NULL,
parent_id INTEGER, -- for threaded comments
author_name TEXT NOT NULL,
author_email TEXT NOT NULL,
author_url TEXT,
content TEXT NOT NULL,
status TEXT DEFAULT 'pending', -- 'pending', 'approved', 'spam', 'trash'
ip_address TEXT,
user_agent TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
FOREIGN KEY (parent_id) REFERENCES comments(id)
);
CREATE INDEX idx_comments_post ON comments(post_id);
CREATE INDEX idx_comments_status ON comments(status);
```
### Authors
```sql
CREATE TABLE authors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER UNIQUE,
name TEXT NOT NULL,
bio TEXT,
avatar TEXT,
social_links TEXT, -- JSON: {"twitter": "...", "linkedin": "..."}
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
```
## API Endpoints
### Public API
```yaml
# Posts
GET /api/posts # List published posts (paginated)
GET /api/posts/:slug # Get post by slug
GET /api/posts/author/:author # Posts by author
GET /api/posts/category/:category # Posts by category
GET /api/posts/tag/:tag # Posts by tag
GET /api/posts/search?q=query # Search posts
# Categories
GET /api/categories # List categories
GET /api/categories/:slug # Get category with posts
# Tags
GET /api/tags # List tags
GET /api/tags/:slug # Get tag with posts
# Comments
GET /api/posts/:slug/comments # Get approved comments
POST /api/posts/:slug/comments # Submit new comment
# Feeds
GET /api/feed/rss # RSS feed
GET /api/feed/atom # Atom feed
GET /api/sitemap.xml # Sitemap
```
### Admin API
```yaml
# Posts
GET /api/admin/posts # List all posts (all statuses)
POST /api/admin/posts # Create post
PUT /api/admin/posts/:id # Update post
DELETE /api/admin/posts/:id # Delete post
POST /api/admin/posts/:id/publish # Publish post
POST /api/admin/posts/:id/archive # Archive post
# Categories
GET /api/admin/categories # List all categories
POST /api/admin/categories # Create category
PUT /api/admin/categories/:id # Update category
DELETE /api/admin/categories/:id # Delete category
# Tags
GET /api/admin/tags # List all tags
POST /api/admin/tags # Create tag
PUT /api/admin/tags/:id # Update tag
DELETE /api/admin/tags/:id # Delete tag
# Comments
GET /api/admin/comments # List comments (all statuses)
PUT /api/admin/comments/:id/approve # Approve comment
PUT /api/admin/comments/:id/spam # Mark as spam
DELETE /api/admin/comments/:id # Delete comment
# Media
POST /api/admin/media/upload # Upload media
GET /api/admin/media # List media
DELETE /api/admin/media/:id # Delete media
```
## Rich Content Features
### Markdown Support
```javascript
// utils/markdown.js
const marked = require('marked');
const hljs = require('highlight.js');
const renderer = {
code(code, language) {
const highlighted = language
? hljs.highlight(code, { language }).value
: code;
return `<pre><code class="hljs ${language}">${highlighted}</code></pre>`;
},
image(href, title, alt) {
return `<figure><img src="${href}" alt="${alt}" loading="lazy"><figcaption>${alt}</figcaption></figure>`;
}
};
marked.use({ renderer });
function parseMarkdown(content) {
return marked.parse(content);
}
function calculateReadingTime(content) {
const words = content.split(/\s+/).length;
return Math.ceil(words / 200); // 200 words per minute
}
```
### Embed Support
```javascript
// utils/embeds.js
const embedPatterns = {
youtube: /(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]+)/,
twitter: /twitter\.com\/\w+\/status\/(\d+)/,
twitter: /twitter\.com\/(\w+)\/status\/(\d+)/,
vimeo: /vimeo\.com\/(\d+)/,
codepen: /codepen\.io\/(\w+)\/pen\/(\w+)/
};
function parseEmbeds(content) {
let parsed = content;
for (const [platform, pattern] of Object.entries(embedPatterns)) {
parsed = parsed.replace(pattern, (match) => {
return generateEmbed(platform, match);
});
}
return parsed;
}
function generateEmbed(platform, url) {
switch (platform) {
case 'youtube':
const videoId = url.match(embedPatterns.youtube)[1];
return `<iframe src="https://www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe>`;
// ... other platforms
}
}
```
## SEO Implementation
### Meta Tags
```javascript
// utils/seo.js
function generateMeta(post) {
return {
title: post.meta_title || `${post.title} | ${config.siteName}`,
description: post.meta_description || post.excerpt,
canonical: post.canonical_url || `${config.siteUrl}/posts/${post.slug}`,
ogType: 'article',
ogImage: post.featured_image,
articlePublishedTime: post.published_at,
articleAuthor: post.author.name
};
}
```
### Structured Data
```javascript
// utils/schema.js
function generateArticleSchema(post) {
return {
"@context": "https://schema.org",
"@type": "Article",
"headline": post.title,
"image": post.featured_image,
"author": {
"@type": "Person",
"name": post.author.name
},
"datePublished": post.published_at,
"dateModified": post.updated_at,
"description": post.excerpt
};
}
```
### Sitemap
```xml
<!-- sitemap.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
{#posts}
<url>
<loc>https://example.com/posts/{slug}</loc>
<lastmod>{updated_at}</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
{/posts}
</urlset>
```
## Comment Moderation
### Spam Detection
```javascript
// services/comments/spam.js
function detectSpam(comment) {
const signals = [];
// Check for spam patterns
if (containsLinks(comment.content) > 3) signals.push('excessive_links');
if (isDuplicate(comment)) signals.push('duplicate');
if (isBlacklisted(comment.ip_address)) signals.push('blacklisted_ip');
if (containsSpamWords(comment.content)) signals.push('spam_words');
// Calculate spam score
const score = signals.length;
return {
isSpam: score >= 2,
score,
signals
};
}
```
## Content Scheduling
```javascript
// services/scheduler.js
async function publishScheduledPosts() {
const now = new Date();
const posts = await db.posts.findAll({
where: {
status: 'draft',
published_at: { [Op.lte]: now }
}
});
for (const post of posts) {
await post.update({ status: 'published' });
await notifySubscribers(post);
await updateSitemap();
}
}
// Run every minute
setInterval(publishScheduledPosts, 60000);
```
## Related Posts
```javascript
// services/related.js
async function getRelatedPosts(post, limit = 5) {
// Find posts with same category or tags
const related = await db.posts.findAll({
where: {
id: { [Op.ne]: post.id },
status: 'published',
[Op.or]: [
{ category_id: post.category_id },
{ '$tags.id$': post.tags.map(t => t.id) }
]
},
include: [db.tags],
limit,
order: [['published_at', 'DESC']]
});
return related;
}
```
## Performance
### Query Optimization
```javascript
// Use joins for efficient loading
const post = await db.posts.findOne({
where: { slug },
include: [
{ model: db.authors, include: [db.users] },
{ model: db.categories },
{ model: db.tags }
]
});
// Paginate efficiently
const posts = await db.posts.findAll({
where: { status: 'published' },
limit: 20,
offset: (page - 1) * 20,
order: [['published_at', 'DESC']]
});
```
### Caching
```javascript
// Cache popular posts
async function getPopularPosts() {
const cacheKey = 'popular-posts';
const cached = await cache.get(cacheKey);
if (cached) return cached;
const posts = await db.posts.findAll({
order: [['view_count', 'DESC']],
limit: 10
});
await cache.set(cacheKey, posts, 3600); // 1 hour
return posts;
}
```
## Security
- Sanitize all user input (HTML, comments)
- Validate author permissions
- Rate limit comments
- Use CSRF protection for forms
- Implement CAPTCHA for guest comments
## Integration Points
- Email subscribers: SendGrid, Mailchimp
- CDN for images: Cloudflare, AWS CloudFront
- Analytics: Google Analytics, Plausible
- Comment systems: Disqus, Facebook Comments
- Search: Algolia, Elasticsearch

View File

@@ -0,0 +1,394 @@
---
name: ecommerce
description: E-commerce domain knowledge - products, carts, orders, payments, inventory management
---
# E-commerce Skill
## Purpose
Provides domain knowledge for building e-commerce systems: product catalogs, shopping carts, order processing, payment integration, and inventory management.
## Capabilities
### Product Catalog
- Product CRUD operations
- Categories and tags
- Product variants (size, color)
- Pricing and discounts
- Product search and filtering
- Image galleries
### Shopping Cart
- Add/remove items
- Quantity updates
- Cart persistence (session/database)
- Price calculations
- Discount codes
### Order Processing
- Order creation from cart
- Order status workflow
- Order history
- Invoice generation
- Email notifications
### Payment Integration
- Stripe integration
- PayPal integration
- Payment status tracking
- Refund processing
- Webhook handling
### Inventory Management
- Stock tracking
- Low stock alerts
- Inventory adjustments
- Supplier management
## Database Schema
### Products
```sql
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sku TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL,
compare_at_price DECIMAL(10, 2),
cost_price DECIMAL(10, 2),
quantity INTEGER DEFAULT 0,
category_id INTEGER,
is_active BOOLEAN DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
CREATE TABLE product_variants (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER NOT NULL,
sku TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
price_adjustment DECIMAL(10, 2) DEFAULT 0,
quantity INTEGER DEFAULT 0,
attributes TEXT, -- JSON: {"size": "M", "color": "red"}
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
parent_id INTEGER,
description TEXT,
image_url TEXT,
FOREIGN KEY (parent_id) REFERENCES categories(id)
);
```
### Cart and Orders
```sql
CREATE TABLE carts (
id TEXT PRIMARY KEY, -- UUID
user_id INTEGER,
session_id TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE cart_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
cart_id TEXT NOT NULL,
product_id INTEGER NOT NULL,
variant_id INTEGER,
quantity INTEGER NOT NULL DEFAULT 1,
price DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (cart_id) REFERENCES carts(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE orders (
id TEXT PRIMARY KEY, -- UUID
order_number TEXT UNIQUE NOT NULL,
user_id INTEGER,
email TEXT NOT NULL,
status TEXT DEFAULT 'pending',
subtotal DECIMAL(10, 2) NOT NULL,
tax DECIMAL(10, 2) DEFAULT 0,
shipping DECIMAL(10, 2) DEFAULT 0,
discount DECIMAL(10, 2) DEFAULT 0,
total DECIMAL(10, 2) NOT NULL,
currency TEXT DEFAULT 'USD',
shipping_address TEXT,
billing_address TEXT,
notes TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
CREATE TABLE order_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id TEXT NOT NULL,
product_id INTEGER NOT NULL,
variant_id INTEGER,
name TEXT NOT NULL,
sku TEXT NOT NULL,
quantity INTEGER NOT NULL,
price DECIMAL(10, 2) NOT NULL,
total DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
CREATE TABLE payments (
id TEXT PRIMARY KEY, -- UUID
order_id TEXT NOT NULL,
provider TEXT NOT NULL, -- 'stripe', 'paypal'
transaction_id TEXT,
amount DECIMAL(10, 2) NOT NULL,
currency TEXT DEFAULT 'USD',
status TEXT DEFAULT 'pending',
metadata TEXT, -- JSON
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
```
### Inventory
```sql
CREATE TABLE inventory_transactions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER,
variant_id INTEGER,
quantity INTEGER NOT NULL,
type TEXT NOT NULL, -- 'purchase', 'sale', 'adjustment', 'return'
reference TEXT, -- order ID, PO ID
notes TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES products(id)
);
```
## API Endpoints
### Public API
```yaml
# Products
GET /api/products # List products (with pagination, filters)
GET /api/products/:slug # Get product by slug
GET /api/categories # List categories
GET /api/categories/:slug # Get category with products
# Cart
GET /api/cart # Get current cart
POST /api/cart/items # Add item to cart
PUT /api/cart/items/:id # Update quantity
DELETE /api/cart/items/:id # Remove item
POST /api/cart/coupon # Apply discount code
# Checkout
POST /api/checkout # Create order from cart
POST /api/checkout/guest # Guest checkout
GET /api/orders/:id # Get order details
```
### Admin API
```yaml
# Products
GET /api/admin/products # List all products
POST /api/admin/products # Create product
PUT /api/admin/products/:id # Update product
DELETE /api/admin/products/:id # Delete product
# Categories
GET /api/admin/categories # List all categories
POST /api/admin/categories # Create category
PUT /api/admin/categories/:id # Update category
DELETE /api/admin/categories/:id # Delete category
# Orders
GET /api/admin/orders # List orders (with filters)
PUT /api/admin/orders/:id # Update order status
POST /api/admin/orders/:id/refund # Process refund
# Inventory
GET /api/admin/inventory # Inventory status
PUT /api/admin/inventory/:id # Update stock
POST /api/admin/inventory/adjust # Stock adjustment
```
## Payment Integration
### Stripe
```javascript
// services/payment/stripe.js
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
async function createPaymentIntent(order) {
const paymentIntent = await stripe.paymentIntents.create({
amount: Math.round(order.total * 100), // cents
currency: order.currency.toLowerCase(),
metadata: { orderId: order.id },
receipt_email: order.email
});
return {
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id
};
}
async function processWebhook(signature, payload) {
const event = stripe.webhooks.constructEvent(
payload,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
switch (event.type) {
case 'payment_intent.succeeded':
await updatePaymentStatus(event.data.object.id, 'completed');
break;
case 'payment_intent.payment_failed':
await updatePaymentStatus(event.data.object.id, 'failed');
break;
}
}
```
### PayPal
```javascript
// services/payment/paypal.js
const paypal = require('@paypal/checkout-server-sdk');
async function createOrder(order) {
const request = new orders.OrdersCreateRequest();
request.requestBody({
intent: 'CAPTURE',
purchase_units: [{
amount: {
currency_code: order.currency,
value: order.total.toFixed(2)
},
reference_id: order.id
}]
});
const response = await client.execute(request);
return response.result;
}
async function captureOrder(orderId) {
const request = new orders.OrdersCaptureRequest(orderId);
const response = await client.execute(request);
return response.result;
}
```
## Order Statuses
| Status | Description | Next Statuses |
|--------|-------------|---------------|
| `pending` | Created, awaiting payment | `processing`, `cancelled` |
| `processing` | Payment confirmed, preparing | `shipped`, `on_hold` |
| `shipped` | Shipped to customer | `delivered` |
| `delivered` | Customer received | `completed` |
| `completed` | Order complete | - |
| `on_hold` | Manual review needed | `processing`, `cancelled` |
| `cancelled` | Order cancelled | `refunded` |
| `refunded` | Money returned to customer | - |
## Email Templates
### Order Confirmation
```html
<h1>Thank you for your order!</h1>
<p>Order #{{order_number}}</p>
<h2>Order Details</h2>
{{#each items}}
<p>{{name}} x{{quantity}} - ${{total}}</p>
{{/each}}
<h2>Total: ${{total}}</h2>
<h2>Shipping Address</h2>
<p>{{shipping_address}}</p>
<p>We'll send you another email when your order ships.</p>
```
### Shipping Notification
```html
<h1>Your order has shipped!</h1>
<p>Order #{{order_number}}</p>
<p>Tracking: {{tracking_number}}</p>
<p>Carrier: {{carrier}}</p>
<h2>Estimated Delivery</h2>
<p>{{estimated_delivery}}</p>
```
## Security Considerations
### Payment Security
- Never store credit card numbers
- Use PCI-compliant payment providers
- Implement CSRF protection
- Use HTTPS everywhere
### Order Fraud Prevention
- Validate shipping address
- Check for suspicious patterns (high value, rush shipping)
- Implement rate limiting on checkout
- Log all order actions
## Performance Optimizations
### Product Listings
- Paginate results (20-50 per page)
- Use database indexes on category, price
- Cache category pages
- Lazy load product images
### Cart Performance
- Store cart in Redis for quick access
- Use database for persistence
- Batch quantity updates
### Inventory Checks
- Real-time stock validation at checkout
- Lock inventory during payment processing
- Handle concurrent purchases gracefully
## Integration Points
- Product Import: CSV, JSON, API
- Shipping Carriers: UPS, FedEx, DHL
- Tax Calculation: TaxJar, Avalara
- Email: SendGrid, Mailgun
- Analytics: Google Analytics, Mixpanel
## Handoff Protocol
After implementation:
1. Test checkout flow end-to-end
2. Verify payment processing
3. Check inventory deduction
4. Test email notifications
5. Verify order status transitions
6. Review `@CodeSkeptic` for security audit