feat: add workflows for CMS, E-commerce, Blog + backend-developer agent + prompt-engineering rules
This commit is contained in:
268
.kilo/agents/backend-developer.md
Normal file
268
.kilo/agents/backend-developer.md
Normal 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
1195
.kilo/commands/blog.md
Normal file
File diff suppressed because it is too large
Load Diff
1270
.kilo/commands/commerce.md
Normal file
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
328
.kilo/rules/prompt-engineering.md
Normal file
328
.kilo/rules/prompt-engineering.md
Normal 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
489
.kilo/skills/blog/SKILL.md
Normal 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
|
||||
394
.kilo/skills/ecommerce/SKILL.md
Normal file
394
.kilo/skills/ecommerce/SKILL.md
Normal 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
|
||||
Reference in New Issue
Block a user