Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:50:06 +08:00
commit 5e3ca965d9
68 changed files with 11257 additions and 0 deletions

534
commands/add-deployment.md Normal file
View File

@@ -0,0 +1,534 @@
Add a new deployment target to your existing Odoo PWA project.
## What this command does:
- Adds deployment configuration for new platforms
- Creates necessary config files
- Sets up CI/CD workflows
- Provides deployment instructions
- Configures environment variables
## Supported Deployment Targets
### Primary (Recommended)
-**Vercel** - Best for full-stack PWAs (API routes work)
-**Netlify** - Great for static + serverless functions
-**Cloudflare Pages** - Fast global CDN, edge functions
### Secondary (Static Only)
- ⚠️ **GitHub Pages** - Free, but no server-side code
- ⚠️ **Cloudflare Pages (Static)** - Without edge functions
- ⚠️ **AWS S3 + CloudFront** - Static hosting only
---
## Prerequisites
Before adding deployment:
```
□ Project builds successfully (npm run build)
□ Odoo connection tested and working
□ Environment variables documented
□ Git repository initialized
□ Code committed to version control
```
---
## Add Vercel Deployment 🔷
### What You'll Get:
- Automatic deployments from Git
- Serverless API routes
- Preview deployments for PRs
- Environment variable management
- Custom domains
- Analytics and logs
### Steps:
#### 1. Install Vercel CLI (Optional)
```bash
npm install -g vercel
```
#### 2. Create `vercel.json`
```json
{
"buildCommand": "npm run build",
"outputDirectory": "build",
"framework": "sveltekit",
"installCommand": "npm install",
"devCommand": "npm run dev",
"env": {
"VITE_ODOO_URL": "@vite_odoo_url",
"VITE_ODOO_DB": "@vite_odoo_db",
"VITE_MODEL_NAME": "@vite_model_name",
"VITE_MODEL_DISPLAY_NAME": "@vite_model_display_name"
},
"build": {
"env": {
"ODOO_API_KEY": "@odoo_api_key",
"ODOO_USERNAME": "@odoo_username"
}
}
}
```
For React/Vue:
```json
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"framework": "vite"
}
```
#### 3. Create `.vercelignore`
```
node_modules
.env
.env.local
*.log
.DS_Store
```
#### 4. Deployment Options
**Option A: Vercel Dashboard (Recommended for first time)**
1. Go to https://vercel.com/new
2. Connect your Git repository
3. Vercel auto-detects framework
4. Add environment variables:
- `VITE_ODOO_URL`
- `VITE_ODOO_DB`
- `ODOO_API_KEY`
- `ODOO_USERNAME`
- `VITE_MODEL_NAME`
- `VITE_MODEL_DISPLAY_NAME`
5. Click "Deploy"
**Option B: Vercel CLI**
```bash
vercel login
vercel
# Follow prompts
# Add environment variables when asked
# Or add them later in dashboard
```
**Option C: Continuous Deployment**
1. Connect repository to Vercel
2. Every push to `main` auto-deploys
3. PRs get preview deployments
#### 5. Configure Environment Variables
In Vercel Dashboard:
1. Go to Project Settings
2. Environment Variables tab
3. Add each variable:
- Production
- Preview (optional)
- Development (optional)
#### 6. Test Deployment
1. Wait for build to complete
2. Visit deployed URL
3. Test Odoo connection
4. Verify all features work
5. Check browser console for errors
---
## Add Netlify Deployment 🟢
### What You'll Get:
- Git-based deployments
- Serverless functions
- Form handling
- Split testing
- Deploy previews
- Custom domains
### Steps:
#### 1. Create `netlify.toml`
```toml
[build]
command = "npm run build"
publish = "build"
[build.environment]
NODE_VERSION = "18"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[functions]
directory = "netlify/functions"
```
For React/Vue:
```toml
[build]
command = "npm run build"
publish = "dist"
```
#### 2. Convert API Routes to Netlify Functions
Create `netlify/functions/odoo.js`:
```javascript
// Copy your API route logic here
// Netlify functions use different format
exports.handler = async (event, context) => {
// Parse request
const body = JSON.parse(event.body);
// Your Odoo logic here
// (copy from src/routes/api/odoo/+server.js)
return {
statusCode: 200,
body: JSON.stringify(result)
};
};
```
#### 3. Update Client to Use Netlify Function
```javascript
// Change API endpoint
const response = await fetch('/.netlify/functions/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
```
#### 4. Deploy
**Option A: Netlify Dashboard**
1. Go to https://app.netlify.com/start
2. Connect repository
3. Configure build settings
4. Add environment variables
5. Deploy
**Option B: Netlify CLI**
```bash
npm install -g netlify-cli
netlify login
netlify init
netlify deploy --prod
```
---
## Add Cloudflare Pages Deployment 🟠
### What You'll Get:
- Global CDN
- Unlimited bandwidth
- Edge functions
- Preview deployments
- Web Analytics
- Fast performance
### Steps:
#### 1. Create `wrangler.toml` (for edge functions)
```toml
name = "odoo-pwa"
compatibility_date = "2025-01-01"
[build]
command = "npm run build"
[build.upload]
format = "service-worker"
```
#### 2. Convert API Routes to Workers
Create `functions/odoo.js`:
```javascript
export async function onRequest(context) {
const { request, env } = context;
// Parse request
const body = await request.json();
// Odoo logic here
// Access env vars via env.ODOO_API_KEY
return new Response(JSON.stringify(result), {
headers: { 'Content-Type': 'application/json' }
});
}
```
#### 3. Deploy
**Option A: Cloudflare Dashboard**
1. Go to Cloudflare Pages
2. Connect Git repository
3. Configure build:
- Build command: `npm run build`
- Output: `build` or `dist`
4. Add environment variables
5. Deploy
**Option B: Wrangler CLI**
```bash
npm install -g wrangler
wrangler login
wrangler pages project create odoo-pwa
wrangler pages publish build
```
---
## Add GitHub Pages Deployment 📘
### ⚠️ Limitations:
- Static hosting only
- No server-side API routes
- Must modify Odoo client for direct API calls
- CORS issues possible
### When to Use:
- Demo projects
- Public apps (no sensitive data)
- Frontend-only versions
### Steps:
#### 1. Update Base Path
**SvelteKit** (`svelte.config.js`):
```javascript
const config = {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: 'index.html'
}),
paths: {
base: process.env.NODE_ENV === 'production'
? '/your-repo-name'
: ''
}
}
};
```
**React/Vue** (`vite.config.js`):
```javascript
export default {
base: '/your-repo-name/'
};
```
#### 2. Create `.github/workflows/deploy.yml`
```yaml
name: Deploy to GitHub Pages
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install
- run: npm run build
env:
VITE_ODOO_URL: ${{ secrets.VITE_ODOO_URL }}
VITE_ODOO_DB: ${{ secrets.VITE_ODOO_DB }}
VITE_MODEL_NAME: ${{ secrets.VITE_MODEL_NAME }}
- uses: actions/upload-pages-artifact@v3
with:
path: build
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/deploy-pages@v4
```
#### 3. Configure Repository
1. Go to Settings → Pages
2. Source: GitHub Actions
3. Save
#### 4. Add Secrets
1. Settings → Secrets and variables → Actions
2. Add each environment variable
#### 5. Push to Deploy
```bash
git add .
git commit -m "Add GitHub Pages deployment"
git push origin main
```
---
## Environment Variables Reference
### Required for All Platforms:
```bash
# Public (VITE_ prefix for client access)
VITE_ODOO_URL=https://yourcompany.odoo.com
VITE_ODOO_DB=yourcompany-main
VITE_MODEL_NAME=x_expense
VITE_MODEL_DISPLAY_NAME=Expense
# Private (server-side only)
ODOO_API_KEY=your_production_api_key
ODOO_USERNAME=your.email@company.com
```
### Platform-Specific:
**Vercel:**
- Add in Project Settings → Environment Variables
- Separate for Production/Preview/Development
**Netlify:**
- Add in Site Settings → Environment Variables
- Or in `netlify.toml`
**Cloudflare:**
- Add in Pages → Settings → Environment Variables
- Or use Wrangler secrets
**GitHub Pages:**
- Add in Repository Settings → Secrets
- Used in GitHub Actions workflow
---
## Post-Deployment Checklist ✅
After deploying to new platform:
```
□ Build completed successfully
□ Application loads at deployment URL
□ Odoo connection works
□ Data syncs correctly
□ CRUD operations work
□ Offline mode functions
□ Service worker registered
□ PWA installs correctly
□ Environment variables set correctly
□ No console errors
□ Tested on mobile
□ Custom domain configured (if needed)
```
---
## Multi-Platform Deployment
### Deploy to Multiple Platforms:
You can deploy the same app to multiple platforms for:
- Redundancy
- A/B testing
- Different regions
- Different audiences
### Example Setup:
```
main branch → Vercel (primary production)
staging branch → Netlify (staging)
PRs → Vercel preview deployments
```
---
## Troubleshooting Deployment
### Build Fails
- Check build logs
- Test `npm run build` locally
- Verify Node version matches
- Check for missing env vars
### App Loads but Doesn't Work
- Check environment variables are set
- Look at browser console errors
- Verify API routes deployed correctly
- Test Odoo connection
### API Routes Not Working
- Verify platform supports server-side code
- Check function logs
- Ensure correct paths used
- Test API endpoint directly
---
## Example prompts to use this command:
- `/add-deployment` - Add new deployment target
- User: "Deploy to Netlify"
- User: "Add Cloudflare deployment"
- User: "Set up continuous deployment"
## Related Commands:
- `/deploy-vercel` - Deploy to Vercel
- `/deploy-github` - Deploy to GitHub Pages
- `/test-connection` - Test before deploying
- `/optimize` - Optimize before production
---
## Best Practices
1. **Use Git-Based Deployment**
- Automatic on push
- Preview deployments
- Easy rollbacks
2. **Separate Environments**
- Development
- Staging
- Production
3. **Secure Secrets**
- Never commit API keys
- Use platform secret management
- Rotate keys regularly
4. **Monitor Deployments**
- Set up error tracking
- Monitor performance
- Watch build times
5. **Test Before Merging**
- Use preview deployments
- Test all features
- Check on real devices

46
commands/add-model.md Normal file
View File

@@ -0,0 +1,46 @@
Add integration for a new Odoo Studio model to an existing PWA project.
## What this command does:
- Invokes the `add-odoo-model` skill
- Creates cache store for the new model
- Adds API methods to the Odoo client
- Generates form and list pages (optional)
- Updates navigation and routing
- Maintains consistency with existing project structure
## Required Information:
Before starting, gather:
1. **Current working directory** - Must be inside an existing Odoo PWA project
2. **Framework** - Detect from project files (SvelteKit/React/Vue)
3. **New model name** (without `x_` prefix, e.g., "task", "product")
4. **Model display name** (human-readable, e.g., "Task", "Product")
5. **Generate UI?** - Whether to create form and list pages (yes/no)
## Steps:
1. Verify the current directory is an Odoo PWA project (check for odoo.js, cache stores)
2. Detect the framework from project structure
3. Ask the user for the new model details
4. Create cache store for the model in `src/lib/stores/` or equivalent
5. Update the Odoo API client with methods for the new model
6. If requested, generate form and list pages/components
7. Update navigation/routing if UI was generated
8. Update documentation with the new model
## Example prompts to use this command:
- `/add-model` - Interactive mode, will ask for all parameters
- User: "Add a task model to my PWA"
- User: "Integrate product catalog from Odoo"
## Validation:
Before proceeding, check:
- Project has `src/lib/odoo.js` or equivalent
- Project has existing cache stores
- `.env` file exists with Odoo configuration
- Framework can be detected
## After adding model:
Remind the user to:
1. Update `.env` with any new model-specific configuration
2. Test the new model's CRUD operations
3. Verify sync functionality works correctly
4. Update any necessary business logic or calculations

734
commands/api-reference.md Normal file
View File

@@ -0,0 +1,734 @@
Complete API reference for the Odoo client and cache stores in generated PWAs.
## What this command does:
- Provides comprehensive API documentation
- Lists all available methods and functions
- Shows parameter types and return values
- Includes code examples for each method
- Helps developers use the generated code effectively
---
## Odoo API Client Reference 🔌
The Odoo API client (`src/lib/odoo.js` or equivalent) provides methods for interacting with Odoo Studio models.
### Configuration
#### Environment Variables
```bash
VITE_ODOO_URL=https://yourcompany.odoo.com
VITE_ODOO_DB=yourcompany-main
ODOO_API_KEY=your_api_key
ODOO_USERNAME=your.email@company.com
VITE_MODEL_NAME=x_expense
```
---
## CRUD Operations
### createRecord()
Create a new record in Odoo.
**Signature:**
```javascript
async function createRecord(model, fields)
```
**Parameters:**
- `model` (string) - Odoo model name (e.g., 'x_expense')
- `fields` (object) - Field values to set
**Returns:** Promise<number> - ID of created record
**Example:**
```javascript
const newId = await odoo.createRecord('x_expense', {
x_studio_description: 'Team lunch',
x_studio_amount: 45.50,
x_studio_date: '2025-01-15',
x_studio_category: 'meal',
x_studio_employee: odoo.formatMany2one(12)
});
console.log(`Created expense with ID: ${newId}`);
```
**Error Handling:**
```javascript
try {
const id = await odoo.createRecord('x_expense', fields);
} catch (error) {
console.error('Failed to create:', error.message);
// Handle error (show message to user, retry, etc.)
}
```
---
### searchRecords()
Search and read records from Odoo.
**Signature:**
```javascript
async function searchRecords(model, domain, fields, limit = null, offset = null)
```
**Parameters:**
- `model` (string) - Odoo model name
- `domain` (array) - Odoo domain filter (e.g., [['id', '>', 100]])
- `fields` (array) - List of field names to fetch
- `limit` (number, optional) - Maximum number of records
- `offset` (number, optional) - Number of records to skip
**Returns:** Promise<Array<Object>> - Array of record objects
**Example:**
```javascript
// Get all expenses
const allExpenses = await odoo.searchRecords(
'x_expense',
[],
['x_studio_description', 'x_studio_amount', 'x_studio_date']
);
// Get expenses > $100
const largeExpenses = await odoo.searchRecords(
'x_expense',
[['x_studio_amount', '>', 100]],
['x_studio_description', 'x_studio_amount']
);
// Get recent 10 expenses
const recentExpenses = await odoo.searchRecords(
'x_expense',
[],
['x_studio_description', 'x_studio_date'],
10 // limit
);
// Get expenses with pagination
const page2 = await odoo.searchRecords(
'x_expense',
[],
fields,
20, // limit: 20 per page
20 // offset: skip first 20 (page 2)
);
```
**Domain Syntax:**
```javascript
// Equals
[['x_studio_status', '=', 'draft']]
// Greater than
[['x_studio_amount', '>', 100]]
// In list
[['x_studio_category', 'in', ['meal', 'travel']]]
// Multiple conditions (AND)
[
['x_studio_amount', '>', 50],
['x_studio_status', '=', 'draft']
]
// OR conditions
['|',
['x_studio_amount', '>', 100],
['x_studio_category', '=', 'travel']
]
// Complex: (amount > 100 OR category = travel) AND status = draft
['&',
'|',
['x_studio_amount', '>', 100],
['x_studio_category', '=', 'travel'],
['x_studio_status', '=', 'draft']
]
```
---
### updateRecord()
Update an existing record.
**Signature:**
```javascript
async function updateRecord(model, id, values)
```
**Parameters:**
- `model` (string) - Odoo model name
- `id` (number) - Record ID to update
- `values` (object) - Fields to update
**Returns:** Promise<boolean> - true if successful
**Example:**
```javascript
await odoo.updateRecord('x_expense', 123, {
x_studio_status: 'approved',
x_studio_amount: 55.00
});
// Update multiple fields
await odoo.updateRecord('x_expense', 123, {
x_studio_description: 'Updated description',
x_studio_date: '2025-01-20',
x_studio_notes: 'Added receipt'
});
```
---
### deleteRecord()
Delete a record from Odoo.
**Signature:**
```javascript
async function deleteRecord(model, id)
```
**Parameters:**
- `model` (string) - Odoo model name
- `id` (number) - Record ID to delete
**Returns:** Promise<boolean> - true if successful
**Example:**
```javascript
await odoo.deleteRecord('x_expense', 123);
// With confirmation
if (confirm('Are you sure you want to delete this expense?')) {
await odoo.deleteRecord('x_expense', expenseId);
}
```
**Error Handling:**
```javascript
try {
await odoo.deleteRecord('x_expense', id);
console.log('Deleted successfully');
} catch (error) {
console.error('Failed to delete:', error.message);
alert('Could not delete: ' + error.message);
}
```
---
## Helper Methods
### fetchPartners()
Fetch partner (res.partner) records.
**Signature:**
```javascript
async function fetchPartners(ids = null)
```
**Parameters:**
- `ids` (array, optional) - Specific partner IDs to fetch. If null, fetches all.
**Returns:** Promise<Array<Object>> - Array of partner objects
**Example:**
```javascript
// Fetch all partners
const allPartners = await odoo.fetchPartners();
// Fetch specific partners
const somePartners = await odoo.fetchPartners([1, 2, 3]);
// Use in dropdown
const partners = await odoo.fetchPartners();
// Display: partners.map(p => ({ value: p.id, label: p.name }))
```
---
### formatMany2one()
Format a Many2one field value for Odoo.
**Signature:**
```javascript
function formatMany2one(id)
```
**Parameters:**
- `id` (number | null) - Partner/record ID
**Returns:** Array<number, boolean> | false - Odoo-formatted value
**Example:**
```javascript
// Set employee field
const fields = {
x_studio_employee: odoo.formatMany2one(12)
// Result: [12, false]
};
// Clear employee field
const fields = {
x_studio_employee: odoo.formatMany2one(null)
// Result: false
};
```
---
### formatMany2many()
Format a Many2many field value for Odoo.
**Signature:**
```javascript
function formatMany2many(ids)
```
**Parameters:**
- `ids` (array) - Array of record IDs
**Returns:** Array - Odoo command format
**Example:**
```javascript
// Set tags (replace all)
const fields = {
x_studio_tags: odoo.formatMany2many([1, 2, 3])
// Result: [[6, 0, [1, 2, 3]]]
};
// Clear tags
const fields = {
x_studio_tags: odoo.formatMany2many([])
// Result: [[6, 0, []]]
};
```
**Odoo Many2many Commands:**
```javascript
// (6, 0, [ids]) - Replace all (what formatMany2many uses)
// (4, id) - Add link to id
// (3, id) - Remove link to id
// (5, 0) - Remove all links
```
---
## Cache Store API Reference 💾
The cache store provides reactive state management with offline-first capabilities.
### Properties
#### records
**Type:** Reactive Array<Object>
Current cached records.
**Example:**
```javascript
// SvelteKit
$: totalAmount = $expenseCache.reduce((sum, e) => sum + e.x_studio_amount, 0);
// React
const totalAmount = useMemo(() =>
records.reduce((sum, e) => sum + e.x_studio_amount, 0),
[records]
);
// Vue
const totalAmount = computed(() =>
expenseStore.records.reduce((sum, e) => sum + e.x_studio_amount, 0)
);
```
#### isLoading
**Type:** Reactive Boolean
Loading state indicator.
**Example:**
```javascript
{#if $expenseCache.isLoading}
<LoadingSpinner />
{:else}
<ExpenseList />
{/if}
```
#### error
**Type:** Reactive String | null
Current error message, if any.
**Example:**
```javascript
{#if $expenseCache.error}
<ErrorAlert message={$expenseCache.error} />
{/if}
```
#### lastSync
**Type:** Reactive Number (timestamp)
Timestamp of last successful sync.
**Example:**
```javascript
const timeSinceSync = Date.now() - $expenseCache.lastSync;
const minutes = Math.floor(timeSinceSync / 60000);
// Display: "Last synced ${minutes} minutes ago"
```
---
### Methods
### load()
Load records from cache and trigger background sync.
**Signature:**
```javascript
async function load()
```
**Returns:** Promise<void>
**Behavior:**
1. Loads from cache immediately (instant UI update)
2. Checks if cache is stale (> 5 minutes)
3. If stale, syncs in background
4. Updates UI when new data arrives
**Example:**
```javascript
// SvelteKit
$effect(() => {
expenseCache.load();
});
// React
useEffect(() => {
expenseCache.load();
}, []);
// Vue
onMounted(() => {
expenseStore.load();
});
```
---
### create()
Create a new record with optimistic update.
**Signature:**
```javascript
async function create(data)
```
**Parameters:**
- `data` (object) - Field values for new record
**Returns:** Promise<number> - ID of created record
**Behavior:**
1. Generates temporary ID
2. Adds to cache immediately (optimistic)
3. Creates in Odoo (background)
4. Replaces temp ID with real ID
5. Rolls back on error
**Example:**
```javascript
try {
const newId = await expenseCache.create({
x_studio_description: 'Lunch meeting',
x_studio_amount: 45.50,
x_studio_date: '2025-01-15',
x_studio_category: 'meal'
});
console.log('Created:', newId);
navigate(`/expenses/${newId}`);
} catch (error) {
alert('Failed to create: ' + error.message);
}
```
---
### update()
Update an existing record.
**Signature:**
```javascript
async function update(id, data)
```
**Parameters:**
- `id` (number) - Record ID
- `data` (object) - Fields to update
**Returns:** Promise<boolean>
**Behavior:**
1. Updates cache immediately (optimistic)
2. Updates in Odoo (background)
3. Rolls back on error
**Example:**
```javascript
await expenseCache.update(123, {
x_studio_amount: 50.00,
x_studio_status: 'submitted'
});
```
---
### delete()
Delete a record.
**Signature:**
```javascript
async function remove(id)
```
**Parameters:**
- `id` (number) - Record ID to delete
**Returns:** Promise<boolean>
**Behavior:**
1. Removes from cache immediately
2. Deletes from Odoo (background)
3. Restores on error
**Example:**
```javascript
if (confirm('Delete this expense?')) {
try {
await expenseCache.remove(123);
navigate('/expenses');
} catch (error) {
alert('Failed to delete: ' + error.message);
}
}
```
---
### refresh()
Force refresh from Odoo.
**Signature:**
```javascript
async function refresh()
```
**Returns:** Promise<void>
**Behavior:**
1. Fetches all records from Odoo
2. Replaces cache
3. Updates UI
**Example:**
```javascript
// Manual refresh button
<button onclick={() => expenseCache.refresh()}>
Refresh
</button>
```
---
### clearCache()
Clear all cached data.
**Signature:**
```javascript
function clearCache()
```
**Returns:** void
**Behavior:**
1. Clears localStorage
2. Clears IndexedDB
3. Resets records to empty array
**Example:**
```javascript
// Logout function
async function logout() {
expenseCache.clearCache();
// Clear other caches
navigate('/login');
}
```
---
## Advanced Patterns
### Custom Filters
```javascript
// Derived store (SvelteKit)
import { derived } from 'svelte/store';
export const draftExpenses = derived(
expenseCache,
$cache => $cache.filter(e => e.x_studio_status === 'draft')
);
// Hook (React)
function useDraftExpenses() {
const { records } = useExpense();
return useMemo(
() => records.filter(e => e.x_studio_status === 'draft'),
[records]
);
}
// Computed (Vue)
const draftExpenses = computed(() =>
expenseStore.records.filter(e => e.x_studio_status === 'draft')
);
```
### Sorting
```javascript
export const sortedExpenses = derived(
expenseCache,
$cache => [...$cache].sort((a, b) =>
b.x_studio_date.localeCompare(a.x_studio_date)
)
);
```
### Search
```javascript
function searchExpenses(query) {
return records.filter(e =>
e.x_studio_description.toLowerCase().includes(query.toLowerCase())
);
}
```
### Grouping
```javascript
function groupByCategory(records) {
return records.reduce((groups, record) => {
const category = record.x_studio_category;
if (!groups[category]) groups[category] = [];
groups[category].push(record);
return groups;
}, {});
}
```
### Aggregation
```javascript
function getTotalByCategory(records) {
return records.reduce((totals, record) => {
const cat = record.x_studio_category;
totals[cat] = (totals[cat] || 0) + record.x_studio_amount;
return totals;
}, {});
}
```
---
## Server Route API Reference 🔐
The server route (`src/routes/api/odoo/+server.js`) handles Odoo communication.
### Endpoint
**URL:** `/api/odoo`
**Method:** POST
**Content-Type:** application/json
### Request Format
```json
{
"action": "create|search|update|delete",
"model": "x_expense",
...parameters
}
```
### Actions
#### create
```json
{
"action": "create",
"model": "x_expense",
"fields": {
"x_studio_description": "Lunch",
"x_studio_amount": 45.50
}
}
```
**Response:** `{ "id": 123 }`
#### search
```json
{
"action": "search",
"model": "x_expense",
"domain": [["id", ">", 100]],
"fields": ["x_studio_description", "x_studio_amount"]
}
```
**Response:** `{ "records": [...] }`
#### update
```json
{
"action": "update",
"model": "x_expense",
"id": 123,
"values": {
"x_studio_amount": 50.00
}
}
```
**Response:** `{ "success": true }`
#### delete
```json
{
"action": "delete",
"model": "x_expense",
"id": 123
}
```
**Response:** `{ "success": true }`
---
## Example prompts to use this command:
- `/api-reference` - Show complete API documentation
- User: "What methods are available in the Odoo client?"
- User: "How do I use the cache store?"
- User: "Show me API examples"
## Next Steps:
- Try the methods in your project
- Review `/examples` for practical use cases
- See `/architecture` for design patterns
- Check `/help` for more information

634
commands/architecture.md Normal file
View File

@@ -0,0 +1,634 @@
Detailed explanation of the Odoo PWA architecture, patterns, and design decisions.
## What this command does:
- Explains the architectural patterns used in generated PWAs
- Details the data flow and state management
- Describes the caching strategy
- Explains offline-first design principles
- Provides insights into technical decisions
---
## Architecture Overview 🏗️
The Odoo PWA Generator creates **offline-first Progressive Web Apps** with a **three-layer architecture** that ensures data availability, performance, and seamless Odoo integration.
```
┌─────────────────────────────────────────┐
│ UI Layer (Components) │
│ - Forms, Lists, Navigation │
│ - Framework-specific (Svelte/React/Vue)│
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ State Layer (Cache Stores) │
│ - Smart Caching Logic │
│ - Dual Storage (localStorage + IndexedDB) │
│ - Background Sync │
│ - Optimistic Updates │
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ API Layer (Odoo Client) │
│ - JSON-RPC Communication │
│ - CRUD Operations │
│ - Field Formatting │
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ Server Layer (API Routes) │
│ - Credential Management │
│ - UID Caching │
│ - Error Handling │
└──────────────┬──────────────────────────┘
┌─────────────────────────────────────────┐
│ Odoo Backend │
│ - Studio Models │
│ - Business Logic │
│ - Data Persistence │
└─────────────────────────────────────────┘
```
---
## Layer 1: UI Components 🎨
### Purpose:
Present data to users and capture user input.
### Responsibilities:
- Render data from cache stores
- Handle user interactions
- Validate form inputs
- Display loading and error states
- Provide responsive, mobile-friendly interface
### Framework-Specific Implementation:
#### SvelteKit
```javascript
<script>
import { expenseCache } from '$lib/stores/expenseCache';
// Reactive to cache updates
$effect(() => {
expenseCache.load();
});
</script>
{#each $expenseCache as expense}
<ExpenseCard {expense} />
{/each}
```
#### React
```javascript
import { useExpense } from './contexts/ExpenseContext';
function ExpenseList() {
const { records, isLoading } = useExpense();
useEffect(() => {
// Load on mount
}, []);
return records.map(expense => (
<ExpenseCard key={expense.id} expense={expense} />
));
}
```
#### Vue
```javascript
<script setup>
import { useExpenseStore } from '@/stores/expenseStore';
const expenseStore = useExpenseStore();
expenseStore.load();
</script>
<template>
<ExpenseCard
v-for="expense in expenseStore.records"
:key="expense.id"
:expense="expense"
/>
</template>
```
### Design Principles:
- **Reactive by default** - UI updates automatically when data changes
- **Loading states** - Show skeleton loaders while data fetches
- **Error boundaries** - Graceful error handling
- **Optimistic UI** - Show changes immediately, sync in background
---
## Layer 2: Cache Stores (State Management) 💾
### Purpose:
Manage application state with offline-first caching.
### The Smart Caching Pattern:
```javascript
// Two-phase load strategy
export async function load() {
// Phase 1: Load from cache (instant)
const cached = await loadFromCache();
records.set(cached); // UI shows data immediately
// Phase 2: Check if stale and sync
if (isCacheStale()) {
await syncInBackground(); // Update in background
}
}
```
### Dual Storage Strategy:
#### localStorage (Metadata)
Stores lightweight metadata:
- `lastSyncTime` - When was last successful sync
- `lastRecordId` - Highest ID fetched so far
- `version` - Cache schema version
```javascript
localStorage.setItem('expenseCache', JSON.stringify({
lastSyncTime: Date.now(),
lastRecordId: 123,
version: 1
}));
```
#### IndexedDB (Master Data)
Stores actual records:
- All record data
- Larger storage capacity
- Async API
- Structured data
```javascript
await db.expenses.bulkPut(records);
```
### Stale Detection:
```javascript
function isCacheStale() {
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
const CACHE_VALIDITY = 5 * 60 * 1000; // 5 minutes
return !cacheData ||
(Date.now() - cacheData.lastSyncTime) > CACHE_VALIDITY;
}
```
### Incremental Sync Pattern:
```javascript
// Only fetch new records, not everything
async function syncInBackground() {
const { lastRecordId } = getCacheMetadata();
// Fetch only records with id > lastRecordId
const newRecords = await odoo.searchRecords(
'x_expense',
[['id', '>', lastRecordId]],
fields
);
if (newRecords.length > 0) {
await appendToCache(newRecords);
updateLastRecordId(newRecords[newRecords.length - 1].id);
}
}
```
### Optimistic Updates:
```javascript
export async function create(data) {
// 1. Generate temporary ID
const tempId = `temp-${Date.now()}`;
const tempRecord = { id: tempId, ...data };
// 2. Update UI immediately
records.update(r => [...r, tempRecord]);
// 3. Create in Odoo (background)
try {
const realId = await odoo.createRecord('x_expense', data);
// 4. Replace temp ID with real ID
records.update(r =>
r.map(rec => rec.id === tempId ? { ...rec, id: realId } : rec)
);
} catch (error) {
// 5. Rollback on error
records.update(r => r.filter(rec => rec.id !== tempId));
throw error;
}
}
```
### Background Sync Timer:
```javascript
let syncInterval;
export function startAutoSync() {
syncInterval = setInterval(() => {
syncInBackground();
}, 3 * 60 * 1000); // Every 3 minutes
}
export function stopAutoSync() {
clearInterval(syncInterval);
}
```
### Partner Resolution Pattern:
```javascript
// Many2one fields return [id, name] or just id
// Resolve partner names and cache them
async function resolvePartnerNames(records) {
const partnerIds = new Set();
// Collect all unique partner IDs
records.forEach(record => {
if (record.x_studio_employee) {
if (Array.isArray(record.x_studio_employee)) {
partnerIds.add(record.x_studio_employee[0]);
} else {
partnerIds.add(record.x_studio_employee);
}
}
});
// Fetch partner names in batch
const partners = await odoo.fetchPartners(Array.from(partnerIds));
const partnerMap = new Map(partners.map(p => [p.id, p.name]));
// Cache for future use
localStorage.setItem('partnerCache', JSON.stringify(
Array.from(partnerMap.entries())
));
return partnerMap;
}
```
---
## Layer 3: API Client (Odoo Communication) 🔌
### Purpose:
Abstract Odoo API communication with clean, reusable methods.
### JSON-RPC Communication:
```javascript
async function jsonRpc(url, params) {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
method: 'call',
params: params,
id: Math.random()
})
});
const data = await response.json();
if (data.error) {
throw new Error(data.error.message);
}
return data.result;
}
```
### CRUD Methods:
#### Create
```javascript
export async function createRecord(model, fields) {
return await fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'create',
model,
fields
})
});
}
```
#### Read
```javascript
export async function searchRecords(model, domain, fields) {
return await fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'search',
model,
domain,
fields
})
});
}
```
#### Update
```javascript
export async function updateRecord(model, id, values) {
return await fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'update',
model,
id,
values
})
});
}
```
#### Delete
```javascript
export async function deleteRecord(model, id) {
return await fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'delete',
model,
id
})
});
}
```
### Field Formatting Helpers:
```javascript
// Many2one: Convert to Odoo format [id, false]
export function formatMany2one(id) {
return id ? [id, false] : false;
}
// Many2many: Convert to Odoo command [(6, 0, [ids])]
export function formatMany2many(ids) {
return ids && ids.length > 0 ? [[6, 0, ids]] : [[6, 0, []]];
}
```
---
## Layer 4: Server Routes (API Proxy) 🔐
### Purpose:
Securely handle Odoo authentication and proxy requests.
### Why Server-Side?
1. **Security** - API keys never exposed to client
2. **CORS** - Bypass cross-origin restrictions
3. **Caching** - Cache UIDs to reduce auth calls
4. **Error Handling** - Centralized error management
### UID Caching Pattern:
```javascript
let cachedUid = null;
async function authenticate() {
if (cachedUid) {
return cachedUid;
}
// Authenticate with Odoo
cachedUid = await odooClient.authenticate(
db, username, apiKey
);
return cachedUid;
}
```
### Action Routing:
```javascript
export async function POST({ request }) {
const { action, model, ...params } = await request.json();
const uid = await authenticate();
switch (action) {
case 'create':
return odooClient.create(model, params.fields);
case 'search':
return odooClient.searchRead(model, params.domain, params.fields);
case 'update':
return odooClient.write(model, params.id, params.values);
case 'delete':
return odooClient.unlink(model, params.id);
default:
throw new Error(`Unknown action: ${action}`);
}
}
```
---
## Data Flow Examples 🔄
### Example 1: Loading Data on Page Load
```
1. User navigates to page
2. Component calls expenseCache.load()
3. Cache store loads from localStorage/IndexedDB
4. UI updates with cached data (instant)
5. Cache checks if data is stale (> 5 min)
6. If stale, triggers background sync
7. API client calls /api/odoo
8. Server authenticates and calls Odoo
9. New records returned
10. Cache updated (localStorage + IndexedDB)
11. UI reactively updates with new data
```
### Example 2: Creating a Record
```
1. User submits form
2. Component calls expenseCache.create(data)
3. Cache creates temp record with temp-ID
4. UI updates immediately (optimistic)
5. API client calls /api/odoo (background)
6. Server creates record in Odoo
7. Real ID returned
8. Cache replaces temp-ID with real ID
9. localStorage and IndexedDB updated
10. UI shows success message
```
### Example 3: Offline Create → Online Sync
```
1. User creates record (offline)
2. Record saved to cache with temp-ID
3. API call fails (no network)
4. Record marked as "pending sync"
5. UI shows "Will sync when online"
[User goes online]
6. Background sync detects pending records
7. Retries API call
8. Success! Real ID received
9. Cache updated
10. UI shows "Synced" status
```
---
## Key Design Patterns 🎯
### 1. Offline-First
- Always load from cache first
- Sync in background
- Queue operations when offline
- Retry on reconnection
### 2. Optimistic UI
- Update UI immediately
- Sync with server in background
- Rollback on error
- Show pending states
### 3. Incremental Sync
- Don't re-fetch all data
- Only fetch new records (id > lastRecordId)
- Reduces bandwidth
- Faster sync times
### 4. Dual Storage
- localStorage for metadata (fast)
- IndexedDB for data (large)
- Best of both worlds
### 5. Partner Resolution
- Batch fetch related records
- Cache partner names
- Avoid N+1 queries
- Display human-readable names
### 6. Reactive State
- Framework-native reactivity
- UI updates automatically
- No manual DOM manipulation
- Cleaner code
---
## Performance Considerations ⚡
### Initial Load:
- Cache-first: Instant data display
- Background sync: Fetch updates without blocking
- IndexedDB: Fast access to large datasets
### Network Usage:
- Incremental sync: Only new data
- Batch operations: Combine requests
- UID caching: Reduce auth calls
### Memory Usage:
- Store large data in IndexedDB, not memory
- Clean up old data periodically
- Lazy load related data
### Bundle Size:
- Framework-specific optimizations
- Tree shaking
- Code splitting
- Lazy load routes
---
## Security Patterns 🔒
### Credential Management:
- API keys in environment variables
- Server-side authentication
- Never expose keys to client
- Rotate keys periodically
### Data Validation:
- Validate on client (UX)
- Validate on server (security)
- Sanitize inputs
- Check permissions
### Error Handling:
- Don't expose internal errors to user
- Log errors securely
- Graceful degradation
- User-friendly messages
---
## Example prompts to use this command:
- `/architecture` - Show architecture details
- User: "How does the caching work?"
- User: "Explain the data flow"
- User: "What design patterns are used?"
## Next Steps:
After understanding the architecture:
1. Review generated code in your project
2. Read CLAUDE.md in your project for specific details
3. Customize patterns for your use case
4. Optimize for your specific needs
For more information, see `/help` or `/examples`!

597
commands/clear-cache.md Normal file
View File

@@ -0,0 +1,597 @@
Clear all cached data from your Odoo PWA application.
## What this command does:
- Clears localStorage cache
- Clears IndexedDB data
- Clears browser cache
- Resets service worker cache
- Forces fresh data fetch from Odoo
- Provides selective clearing options
## When to Use This Command
### ✅ Good Reasons:
- Data appears corrupted or inconsistent
- Testing fresh installation
- After Odoo schema changes
- Debugging sync issues
- After major updates
- Stuck with old data
### ⚠️ Caution:
- Clears all offline data
- May lose unsyncedchanges
- Requires re-download of all data
- User will need to be online
---
## Quick Clear Options
### Option 1: Clear from Browser Console (Fastest)
```javascript
// Clear localStorage
localStorage.clear();
// Clear and refresh
localStorage.clear();
location.reload();
```
### Option 2: Clear from Cache Store
```javascript
// Using cache store method
expenseCache.clearCache();
expenseCache.refresh();
```
### Option 3: Clear from UI
Add a button to your app:
```javascript
<button onclick={() => {
if (confirm('Clear all cached data?')) {
expenseCache.clearCache();
expenseCache.refresh();
}
}}>
Clear Cache
</button>
```
---
## Complete Clear Procedure
### Step 1: Prepare
```
□ Save any unsaved work
□ Ensure internet connection
□ Note current state (for comparison)
□ Close other tabs with same app
```
### Step 2: Clear localStorage
```javascript
// Clear all
localStorage.clear();
// Or clear specific keys
localStorage.removeItem('expenseCache');
localStorage.removeItem('taskCache');
localStorage.removeItem('partnerCache');
```
### Step 3: Clear IndexedDB
```javascript
// Via DevTools:
// 1. Open DevTools (F12)
// 2. Go to Application tab
// 3. Expand IndexedDB in left sidebar
// 4. Right-click on database → Delete
// Or programmatically:
indexedDB.deleteDatabase('odoo-pwa-db');
```
### Step 4: Clear Service Worker Cache
```javascript
// Unregister service worker
navigator.serviceWorker.getRegistrations()
.then(registrations => {
registrations.forEach(reg => reg.unregister());
});
// Clear all caches
caches.keys()
.then(keys => Promise.all(
keys.map(key => caches.delete(key))
));
```
### Step 5: Clear Browser Cache
```
Chrome/Edge: Ctrl+Shift+Delete → Select cache → Clear
Firefox: Ctrl+Shift+Delete → Select cache → Clear now
Safari: Cmd+Option+E
```
### Step 6: Hard Refresh
```
Windows/Linux: Ctrl+Shift+R or Ctrl+F5
Mac: Cmd+Shift+R
```
### Step 7: Verify
```javascript
// Check localStorage is empty
console.log('localStorage size:', localStorage.length);
// Check IndexedDB
// DevTools → Application → IndexedDB
// Should be empty or recreated
// Check cache stores
console.log('Records:', $expenseCache.length);
// Should be 0 or freshly fetched
```
---
## Selective Clearing
### Clear Only Specific Model Cache
```javascript
// Clear just expense cache
localStorage.removeItem('expenseCache');
// Refresh that cache
expenseCache.refresh();
```
### Clear Only Metadata (Keep Records)
```javascript
// Get current cache data
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
// Reset only metadata
cacheData.lastSyncTime = 0;
cacheData.lastRecordId = 0;
// Save back
localStorage.setItem('expenseCache', JSON.stringify(cacheData));
// Force sync
expenseCache.refresh();
```
### Clear Only Old Records
```javascript
// Keep only recent records (last 30 days)
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
expenseCache.records.update(records =>
records.filter(r => new Date(r.x_studio_date) > thirtyDaysAgo)
);
```
---
## Framework-Specific Clearing
### SvelteKit
```javascript
// Clear and reset store
import { expenseCache } from '$lib/stores/expenseCache';
expenseCache.clearCache();
expenseCache.load(); // Reload fresh data
```
### React
```javascript
// Using Context
import { useExpense } from './contexts/ExpenseContext';
function ClearCacheButton() {
const { clearCache, refresh } = useExpense();
return (
<button onClick={() => {
clearCache();
refresh();
}}>
Clear Cache
</button>
);
}
```
### Vue
```javascript
// Using Pinia store
import { useExpenseStore } from '@/stores/expenseStore';
const expenseStore = useExpenseStore();
function clearAndRefresh() {
expenseStore.clearCache();
expenseStore.load();
}
```
---
## Advanced Cache Management
### Schedule Automatic Cache Clear
```javascript
// Clear cache older than 7 days
const CACHE_MAX_AGE = 7 * 24 * 60 * 60 * 1000; // 7 days
function checkCacheAge() {
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
if (cacheData && cacheData.lastSyncTime) {
const age = Date.now() - cacheData.lastSyncTime;
if (age > CACHE_MAX_AGE) {
console.log('Cache too old, clearing...');
expenseCache.clearCache();
expenseCache.refresh();
}
}
}
// Check on app load
checkCacheAge();
```
### Clear on Version Change
```javascript
// In cache store
const CACHE_VERSION = 2; // Increment when schema changes
function checkCacheVersion() {
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
if (!cacheData || cacheData.version !== CACHE_VERSION) {
console.log('Cache version mismatch, clearing...');
clearCache();
// Set new version
localStorage.setItem('expenseCache', JSON.stringify({
version: CACHE_VERSION,
lastSyncTime: 0,
lastRecordId: 0
}));
}
}
```
### Clear Based on Storage Quota
```javascript
// Check storage usage
if (navigator.storage && navigator.storage.estimate) {
navigator.storage.estimate().then(estimate => {
const percentUsed = (estimate.usage / estimate.quota) * 100;
console.log(`Storage: ${percentUsed.toFixed(2)}% used`);
if (percentUsed > 90) {
console.warn('Storage almost full, clearing old cache...');
clearOldestRecords();
}
});
}
function clearOldestRecords() {
// Keep only most recent 100 records
expenseCache.records.update(records =>
records
.sort((a, b) => b.id - a.id)
.slice(0, 100)
);
}
```
---
## Cache Verification
### After Clearing, Verify:
#### 1. Storage is Empty
```javascript
console.log('localStorage keys:', Object.keys(localStorage));
// Should be [] or minimal
console.log('localStorage size:', localStorage.length);
// Should be 0 or very small
```
#### 2. IndexedDB is Clear
```
DevTools → Application → IndexedDB
- Check if database exists
- Check if tables are empty
```
#### 3. Fresh Data Loads
```javascript
// Refresh and watch console
location.reload();
// Should see:
// "Cache miss, fetching from Odoo..."
// "Fetched X records"
```
#### 4. Functionality Works
```
□ Data loads correctly
□ CRUD operations work
□ Sync happens
□ Offline mode works after re-caching
```
---
## Troubleshooting Clear Issues
### Issue: Cache Won't Clear
**Solution 1: Force with DevTools**
```
1. Open DevTools (F12)
2. Application tab
3. Clear storage section
4. Check all boxes
5. Click "Clear site data"
```
**Solution 2: Use Private/Incognito**
```
Open app in private browsing mode
- Fresh session, no cache
- Test functionality
```
**Solution 3: Different Browser**
```
Test in different browser
- Rules out browser-specific issues
```
### Issue: Data Reappears After Clear
**Solution: Check Multiple Sources**
```javascript
// Clear all possible locations
localStorage.clear();
sessionStorage.clear();
indexedDB.deleteDatabase('odoo-pwa-db');
// Unregister service workers
navigator.serviceWorker.getRegistrations()
.then(regs => regs.forEach(reg => reg.unregister()));
// Clear all caches
caches.keys()
.then(keys => Promise.all(keys.map(k => caches.delete(k))));
```
### Issue: App Breaks After Clear
**Solution: Ensure Graceful Degradation**
```javascript
// In cache store, handle missing cache
function loadFromCache() {
try {
const cached = localStorage.getItem('expenseCache');
if (!cached) {
console.log('No cache, will fetch from Odoo');
return { records: [], lastRecordId: 0, lastSyncTime: 0 };
}
return JSON.parse(cached);
} catch (error) {
console.error('Error loading cache:', error);
return { records: [], lastRecordId: 0, lastSyncTime: 0 };
}
}
```
---
## User-Facing Clear Options
### Settings Page Example
```javascript
<script>
import { expenseCache, taskCache } from '$lib/stores';
async function clearAll() {
if (confirm('Clear all cached data? This cannot be undone.')) {
expenseCache.clearCache();
taskCache.clearCache();
alert('Cache cleared! Refreshing...');
location.reload();
}
}
async function clearExpenses() {
if (confirm('Clear expense cache?')) {
expenseCache.clearCache();
await expenseCache.refresh();
alert('Expense cache cleared!');
}
}
function getCacheInfo() {
const size = new Blob(Object.values(localStorage)).size;
const sizeKB = (size / 1024).toFixed(2);
return { count: localStorage.length, sizeKB };
}
</script>
<div class="settings">
<h2>Cache Management</h2>
<div class="cache-info">
<p>Items: {getCacheInfo().count}</p>
<p>Size: {getCacheInfo().sizeKB} KB</p>
<p>Last sync: {new Date($expenseCache.lastSync).toLocaleString()}</p>
</div>
<div class="actions">
<button on:click={clearExpenses}>Clear Expense Cache</button>
<button on:click={clearAll} class="danger">Clear All Cache</button>
</div>
</div>
<style>
.danger {
background: red;
color: white;
}
</style>
```
---
## Cache Clear Checklist ✅
Before clearing:
```
□ Save any unsaved work
□ Note current state
□ Ensure internet connection
□ Close duplicate tabs
```
After clearing:
```
□ localStorage is empty
□ IndexedDB is cleared
□ Service worker cache cleared
□ Fresh data loaded
□ Functionality tested
□ Sync works correctly
□ Offline mode re-enabled (after cache rebuilt)
```
---
## Best Practices
### 1. Clear Strategically
- Don't clear unnecessarily
- Clear only what's needed
- Keep user data when possible
### 2. Warn Users
```javascript
function clearCache() {
const message = `
This will clear all cached data.
You'll need to re-download everything from Odoo.
Continue?
`;
if (confirm(message)) {
// Proceed
}
}
```
### 3. Provide Progress
```javascript
async function clearAndRefresh() {
alert('Clearing cache...');
localStorage.clear();
alert('Fetching fresh data...');
await expenseCache.refresh();
alert('Done! Cache rebuilt.');
}
```
### 4. Log for Debugging
```javascript
function clearCache() {
console.log('Before clear:', {
localStorage: localStorage.length,
records: $expenseCache.length
});
localStorage.clear();
expenseCache.clearCache();
console.log('After clear:', {
localStorage: localStorage.length,
records: $expenseCache.length
});
}
```
### 5. Test Regularly
- Test cache clear functionality
- Ensure app works after clear
- Verify data re-downloads
- Check offline mode recovers
---
## Example prompts to use this command:
- `/clear-cache` - Clear all cached data
- User: "Clear my cache"
- User: "Data looks wrong, clear everything"
- User: "Reset the app"
## Related Commands:
- `/fix-sync` - If sync issues persist
- `/test-connection` - Test after clearing
- `/troubleshoot` - For other issues
- `/help` - Full documentation
---
## Quick Reference
### Clear Everything (Nuclear Option)
```javascript
// Copy-paste into console
localStorage.clear();
sessionStorage.clear();
indexedDB.databases().then(dbs =>
dbs.forEach(db => indexedDB.deleteDatabase(db.name))
);
navigator.serviceWorker.getRegistrations().then(regs =>
regs.forEach(reg => reg.unregister())
);
caches.keys().then(keys =>
keys.forEach(key => caches.delete(key))
);
location.reload(true);
```
### Clear Specific Model
```javascript
localStorage.removeItem('expenseCache');
expenseCache.refresh();
```
### Reset Metadata Only
```javascript
const cache = JSON.parse(localStorage.getItem('expenseCache'));
cache.lastSyncTime = 0;
cache.lastRecordId = 0;
localStorage.setItem('expenseCache', JSON.stringify(cache));
expenseCache.refresh();
```

View File

@@ -0,0 +1,89 @@
Create a smart cache store for an Odoo model with offline-first capabilities.
## What this command does:
- Creates a framework-specific cache store (Svelte store, React Context, or Vue Pinia)
- Implements dual storage (localStorage + IndexedDB)
- Adds smart caching with stale detection (5-minute validity)
- Implements background sync (3-minute intervals)
- Includes incremental fetching (only new records)
- Adds partner name resolution and caching
- Implements optimistic updates
## Required Information:
Before starting, gather:
1. **Current working directory** - Must be inside an Odoo PWA project
2. **Framework** - Detect from project files (SvelteKit/React/Vue)
3. **Model name** (without `x_` prefix, e.g., "expense", "task")
4. **Model display name** (human-readable, e.g., "Expense", "Task")
5. **Fields to fetch** - Array of Odoo fields (e.g., ["x_studio_name", "x_studio_amount"])
## Store Features:
The generated cache store will include:
- `records` - Reactive array of cached records
- `isLoading` - Loading state indicator
- `error` - Error state
- `lastSync` - Timestamp of last successful sync
- `load()` - Load from cache and trigger background sync
- `create(data)` - Create new record with optimistic update
- `update(id, data)` - Update record with optimistic update
- `delete(id)` - Delete record with optimistic update
- `refresh()` - Force refresh from Odoo
- `clearCache()` - Clear all cached data
## Storage Strategy:
1. **localStorage**: Stores metadata (lastSyncTime, lastRecordId, version)
2. **IndexedDB**: Stores master data (all records)
3. **Stale detection**: Cache considered stale after 5 minutes
4. **Background sync**: Automatic sync every 3 minutes
5. **Incremental fetch**: Only fetches records with `id > lastRecordId`
## Steps:
1. Verify the current directory is an Odoo PWA project
2. Detect the framework from project structure
3. Ask the user for model details and fields
4. Create cache store file in appropriate location:
- SvelteKit: `src/lib/stores/{model}Cache.js`
- React: `src/contexts/{Model}Context.jsx`
- Vue: `src/stores/{model}Store.js`
5. Import and register the store in the appropriate location
6. Provide usage examples and documentation
## Example prompts to use this command:
- `/create-cache-store` - Interactive mode
- User: "Create a cache store for the task model"
- User: "Add caching for product catalog"
## After creation:
Remind the user to:
1. Import the store in components that need it
2. Call the `load()` method when the component mounts
3. Use reactive data bindings to display records
4. Test create, update, and delete operations
5. Verify offline functionality works correctly
## Usage Examples:
### SvelteKit
```javascript
import { taskCache } from '$lib/stores/taskCache';
// In +page.svelte
$effect(() => {
taskCache.load();
});
```
### React
```javascript
import { useTask } from './contexts/TaskContext';
const { records, create, update } = useTask();
```
### Vue
```javascript
import { useTaskStore } from '@/stores/taskStore';
const taskStore = useTaskStore();
taskStore.load();
```

182
commands/deploy-github.md Normal file
View File

@@ -0,0 +1,182 @@
Deploy your Odoo PWA to GitHub Pages with GitHub Actions for continuous deployment.
## What this command does:
- Sets up GitHub Actions workflow for automated deployment
- Configures GitHub Pages in repository settings
- Sets up repository secrets for environment variables
- Deploys the application to GitHub Pages
- Provides custom domain setup instructions
## Prerequisites:
Before deploying, verify:
1. ✅ Project builds successfully locally (`npm run build`)
2. ✅ Git repository exists and is pushed to GitHub
3. ✅ User has admin access to the repository
4. ✅ GitHub Pages is enabled in repository settings
5. ✅ Base URL configuration is correct for GitHub Pages
## Important: GitHub Pages Limitations
⚠️ Note: GitHub Pages is static hosting only. Server-side API routes won't work.
**Recommendation**: For full Odoo PWA functionality with server-side API proxy:
- Use Vercel, Cloudflare Pages, or Netlify instead
- Or deploy API routes separately (e.g., Vercel Serverless Functions)
## If Continuing with GitHub Pages:
You'll need to modify the Odoo client to use CORS-enabled direct Odoo API calls or deploy API routes separately.
## Steps:
### 1. Configure GitHub Repository
```bash
# Ensure you're on main branch
git checkout main
git pull origin main
```
### 2. Set Up GitHub Actions Workflow
Check if `.github/workflows/deploy.yml` exists:
- If yes: Review and update if needed
- If no: Create the workflow file
### 3. Configure Repository Secrets
Go to: Repository → Settings → Secrets and variables → Actions
Add these secrets:
```
ODOO_API_KEY=your_production_api_key
ODOO_USERNAME=your.email@company.com
VITE_ODOO_URL=https://yourcompany.odoo.com
VITE_ODOO_DB=yourcompany-main
VITE_MODEL_NAME=x_expense
VITE_MODEL_DISPLAY_NAME=Expense
```
### 4. Enable GitHub Pages
Repository → Settings → Pages:
- Source: Deploy from a branch
- Branch: `gh-pages` (will be created by Actions)
- Folder: `/ (root)`
### 5. Update Base Path
For framework-specific configuration:
**SvelteKit** (`svelte.config.js`):
```javascript
paths: {
base: process.env.NODE_ENV === 'production' ? '/your-repo-name' : ''
}
```
**React/Vue** (`vite.config.js`):
```javascript
base: process.env.NODE_ENV === 'production' ? '/your-repo-name/' : '/'
```
### 6. Commit and Push
```bash
git add .
git commit -m "Configure GitHub Pages deployment"
git push origin main
```
### 7. Monitor Deployment
- Go to Actions tab in GitHub
- Watch the deployment workflow
- Check for any errors
## GitHub Actions Workflow
The workflow should:
1. Trigger on push to `main` branch
2. Install dependencies
3. Build the project with environment variables
4. Deploy to `gh-pages` branch
5. GitHub Pages automatically serves from `gh-pages`
## Example Workflow (.github/workflows/deploy.yml):
```yaml
name: Deploy to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install
- run: npm run build
env:
VITE_ODOO_URL: ${{ secrets.VITE_ODOO_URL }}
VITE_ODOO_DB: ${{ secrets.VITE_ODOO_DB }}
VITE_MODEL_NAME: ${{ secrets.VITE_MODEL_NAME }}
VITE_MODEL_DISPLAY_NAME: ${{ secrets.VITE_MODEL_DISPLAY_NAME }}
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
```
## Custom Domain Setup (Optional):
1. Add `CNAME` file to `static` folder with your domain
2. Configure DNS records:
- A record: Points to GitHub Pages IPs
- Or CNAME: Points to `username.github.io`
3. Enable HTTPS in repository settings (automatic)
## Post-Deployment Checks:
After deployment, verify:
1. ✅ Application loads at `https://username.github.io/repo-name`
2. ✅ All assets load correctly (check browser console)
3. ✅ Base path is correct for all routes
4. ✅ Odoo connection works (may need CORS configuration)
5. ✅ PWA installs correctly
## Example prompts to use this command:
- `/deploy-github` - Interactive GitHub Pages deployment
- User: "Deploy to GitHub Pages"
- User: "Set up GitHub Actions for my PWA"
## Troubleshooting:
### Build Fails in Actions
- Check Actions logs for specific error
- Verify all secrets are set correctly
- Ensure Node version is compatible
- Test build locally first
### 404 on GitHub Pages
- Verify `gh-pages` branch exists
- Check GitHub Pages settings
- Ensure base path is configured
- Wait a few minutes for DNS propagation
### Assets Not Loading
- Check base path configuration
- Verify all asset paths are relative
- Look for CORS issues in console
- Ensure service worker paths are correct
### API Routes Don't Work
- GitHub Pages doesn't support server-side code
- Deploy API routes to Vercel/Netlify separately
- Or modify Odoo client for direct API calls with CORS
## After Deployment:
Provide the user with:
1. GitHub Pages URL
2. Link to Actions tab for monitoring
3. Instructions for custom domain setup
4. Reminder about server-side limitations
5. Alternative hosting recommendations if needed

144
commands/deploy-vercel.md Normal file
View File

@@ -0,0 +1,144 @@
Deploy your Odoo PWA to Vercel with proper environment variable configuration.
## What this command does:
- Prepares the project for Vercel deployment
- Guides through Vercel CLI setup or web deployment
- Configures environment variables securely
- Sets up continuous deployment from Git
- Provides post-deployment verification steps
## Prerequisites:
Before deploying, verify:
1. ✅ Project builds successfully locally (`npm run build`)
2. ✅ All tests pass
3.`.env` file is configured and working
4. ✅ Git repository is initialized and pushed to GitHub/GitLab/Bitbucket
5. ✅ Vercel account exists (or guide user to create one)
## Deployment Options:
### Option 1: Vercel CLI (Recommended for first deployment)
```bash
npm install -g vercel
vercel login
vercel
```
### Option 2: Vercel Dashboard (Recommended for Git integration)
1. Go to https://vercel.com/new
2. Import your Git repository
3. Configure project settings
4. Add environment variables
5. Deploy
## Environment Variables to Set in Vercel:
Required for production:
```
VITE_ODOO_URL=https://yourcompany.odoo.com
VITE_ODOO_DB=yourcompany-main
ODOO_API_KEY=your_production_api_key
ODOO_USERNAME=your.email@company.com
VITE_MODEL_NAME=x_expense
VITE_MODEL_DISPLAY_NAME=Expense
```
## Steps:
1. Verify project builds successfully
2. Check if Vercel is already configured (look for `vercel.json`)
3. Ask user which deployment option they prefer
4. Guide through the chosen deployment method
5. Help set up environment variables in Vercel dashboard
6. Initiate deployment
7. Wait for build to complete
8. Test the deployed application
9. Set up custom domain (if requested)
## Framework-Specific Configuration:
### SvelteKit
Verify `vercel.json` contains:
```json
{
"buildCommand": "npm run build",
"outputDirectory": "build",
"framework": "sveltekit"
}
```
### React
Verify build settings:
```json
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"framework": "vite"
}
```
### Vue
Verify build settings:
```json
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"framework": "vite"
}
```
## Post-Deployment Checks:
After deployment, verify:
1. ✅ Application loads correctly
2. ✅ Odoo connection works (check browser console)
3. ✅ Data syncs from Odoo
4. ✅ CRUD operations work
5. ✅ Offline functionality works
6. ✅ PWA can be installed
7. ✅ Service worker is active
## Example prompts to use this command:
- `/deploy-vercel` - Interactive deployment wizard
- User: "Deploy my PWA to Vercel"
- User: "Help me set up Vercel deployment"
## Continuous Deployment:
Once Git integration is set up:
- Every push to `main` branch triggers automatic deployment
- Preview deployments for pull requests
- Automatic rollback on build failures
- Environment variables persist across deployments
## Custom Domain Setup:
If user wants a custom domain:
1. Go to Vercel Dashboard → Project → Settings → Domains
2. Add custom domain
3. Configure DNS records as shown
4. Wait for SSL certificate provisioning (automatic)
5. Test HTTPS access
## Troubleshooting:
### Build Fails
- Check build logs in Vercel dashboard
- Verify all dependencies are in package.json
- Ensure Node version is compatible
- Check for environment-specific code
### Environment Variables Not Working
- Verify variables are set in Vercel dashboard
- Check variable names match exactly (case-sensitive)
- Ensure variables starting with `VITE_` for client-side access
- Redeploy after adding new variables
### API Routes Not Working
- Verify serverless functions are in correct directory
- Check function size limits (< 50MB)
- Review function logs in Vercel dashboard
- Ensure API routes use correct paths
## After Deployment:
Provide the user with:
1. Deployed URL
2. Vercel dashboard link
3. Instructions for adding custom domain
4. Tips for monitoring performance
5. Reminder to update API keys for production

467
commands/examples.md Normal file
View File

@@ -0,0 +1,467 @@
Real-world usage examples and scenarios for the Odoo PWA Generator plugin.
## What this command does:
- Provides practical, real-world examples of using the plugin
- Shows complete workflows from start to finish
- Demonstrates different use cases and scenarios
- Includes code samples and best practices
- Helps users understand the plugin's capabilities
## Example 1: Expense Tracking App 💰
### Business Need:
Create a mobile-friendly app for employees to track expenses on-the-go, even without internet connection. Sync with Odoo for approval and reimbursement.
### Odoo Model Setup:
In Odoo Studio, create model `x_expense` with fields:
- `x_studio_description` (Char) - Expense description
- `x_studio_amount` (Float) - Amount spent
- `x_studio_date` (Date) - When expense occurred
- `x_studio_category` (Selection) - Meal, Travel, Hotel, Other
- `x_studio_receipt` (Binary) - Photo of receipt
- `x_studio_employee` (Many2one to res.partner) - Who spent it
- `x_studio_status` (Selection) - Draft, Submitted, Approved, Paid
### Implementation Steps:
```
1. /new-svelte-pwa
- Project name: expense-tracker
- Model: expense
- Display name: Expense
- Deployment: vercel
2. cd expense-tracker
3. /init-project
- Install dependencies
- Configure Odoo credentials
- Test connection
4. Customize the UI:
- Add category filter
- Display total amount
- Add receipt upload
- Status badge colors
5. /deploy-vercel
- Deploy to production
- Share with team
```
### Key Features:
- ✅ Record expenses offline
- ✅ Take photos of receipts
- ✅ Categorize expenses
- ✅ Auto-sync when online
- ✅ View approval status
- ✅ Calculate monthly totals
### Code Customization:
```javascript
// Add total calculation to cache store
export const totalExpenses = derived(expenseCache, $cache => {
return $cache.reduce((sum, exp) => sum + exp.x_studio_amount, 0);
});
// Add category filter
export function filterByCategory(category) {
return $expenseCache.filter(e => e.x_studio_category === category);
}
```
---
## Example 2: Inventory Management System 📦
### Business Need:
Warehouse staff need to check stock levels, update quantities, and add new inventory items from mobile devices or tablets, even in areas with poor connectivity.
### Odoo Model Setup:
Create model `x_inventory` with fields:
- `x_studio_sku` (Char) - Product SKU
- `x_studio_name` (Char) - Product name
- `x_studio_quantity` (Integer) - Current stock
- `x_studio_location` (Char) - Warehouse location
- `x_studio_min_quantity` (Integer) - Reorder threshold
- `x_studio_supplier` (Many2one to res.partner) - Supplier
- `x_studio_last_restock` (Date) - Last restock date
### Implementation Steps:
```
1. /new-react-pwa
- Project name: inventory-manager
- Model: inventory
- Display name: Inventory Item
- Deployment: vercel
2. cd inventory-manager
3. /init-project
4. Add barcode scanning:
- npm install @zxing/library
- Add scanner component
- Look up items by SKU
5. Add low stock alerts:
- Filter items where quantity < min_quantity
- Show notification badge
- Sort by urgency
6. /deploy-vercel
```
### Key Features:
- ✅ Scan barcodes to find items
- ✅ Update quantities offline
- ✅ Low stock alerts
- ✅ Search by name or SKU
- ✅ Filter by location
- ✅ Auto-sync updates
### Code Customization:
```javascript
// Add low stock filter
const lowStockItems = useMemo(() => {
return records.filter(item =>
item.x_studio_quantity < item.x_studio_min_quantity
);
}, [records]);
// Add barcode lookup
async function lookupBySKU(sku) {
return records.find(item => item.x_studio_sku === sku);
}
```
---
## Example 3: Field Service CRM 🔧
### Business Need:
Field technicians need to view customer information, log service calls, and update job status while on-site, often without reliable internet.
### Odoo Model Setup:
Create model `x_service_call` with fields:
- `x_studio_customer` (Many2one to res.partner) - Customer
- `x_studio_issue` (Text) - Problem description
- `x_studio_status` (Selection) - Scheduled, In Progress, Completed
- `x_studio_scheduled_date` (Datetime) - When to visit
- `x_studio_technician` (Many2one to res.partner) - Assigned tech
- `x_studio_notes` (Text) - Service notes
- `x_studio_parts_used` (Char) - Parts replaced
- `x_studio_duration` (Float) - Hours spent
### Implementation Steps:
```
1. /new-vue-pwa
- Project name: field-service-crm
- Model: service_call
- Display name: Service Call
- Deployment: vercel
2. /init-project
3. Add customer details:
- Create customer cache store
- /add-model
- Model: customer (use res.partner)
- Generate UI: no (use existing)
4. Add map integration:
- npm install @googlemaps/js-api-loader
- Show customer locations
- Route planning
5. Add time tracking:
- Start/stop timer
- Calculate duration
- Generate timesheet
6. /deploy-vercel
```
### Key Features:
- ✅ View today's schedule
- ✅ Customer contact info
- ✅ Log service notes offline
- ✅ Track time spent
- ✅ Update job status
- ✅ View service history
---
## Example 4: Sales Order Entry 🛒
### Business Need:
Sales reps at trade shows need to take orders offline and sync them with Odoo when they get back online.
### Odoo Model Setup:
Create model `x_sales_order` with fields:
- `x_studio_customer` (Many2one to res.partner)
- `x_studio_date` (Date)
- `x_studio_items` (Text/JSON) - Line items
- `x_studio_total` (Float) - Order total
- `x_studio_status` (Selection) - Draft, Sent, Confirmed
- `x_studio_notes` (Text) - Special instructions
- `x_studio_salesperson` (Many2one to res.partner)
### Implementation Steps:
```
1. /new-svelte-pwa
- Project name: sales-order-entry
- Model: sales_order
- Display name: Sales Order
2. /add-model
- Model: customer (res.partner)
- Add product catalog model
3. Build line item editor:
- Add/remove products
- Quantity and price
- Calculate totals
4. Add customer search:
- Autocomplete
- Recently viewed
- New customer form
5. /deploy-vercel
```
### Key Features:
- ✅ Search products
- ✅ Build order offline
- ✅ Calculate totals
- ✅ Customer lookup
- ✅ Sync when online
- ✅ Email confirmation
---
## Example 5: Multi-Model Project Management 📋
### Business Need:
Manage projects with tasks, time entries, and documents, all syncing with Odoo.
### Multiple Models:
1. `x_project` - Projects
2. `x_task` - Tasks
3. `x_time_entry` - Time tracking
4. `x_document` - File attachments
### Implementation Steps:
```
1. /new-svelte-pwa
- Project name: project-manager
- Model: project
- Display name: Project
2. /add-model
- Model: task
- Generate UI: yes
3. /add-model
- Model: time_entry
- Generate UI: yes
4. /add-model
- Model: document
- Generate UI: yes
5. Add relationships:
- Tasks belong to projects
- Time entries belong to tasks
- Documents belong to projects
6. Build dashboard:
- Project overview
- Task list by status
- Total hours tracked
- Recent documents
7. /deploy-vercel
```
### Key Features:
- ✅ Multiple model types
- ✅ Relationships between models
- ✅ Aggregate data (total hours)
- ✅ Complex filtering
- ✅ Dashboard views
---
## Example 6: Custom Cache Strategy 🎯
### Scenario:
Need a custom caching strategy for frequently changing data.
### Implementation:
```
1. Open existing project
2. /create-cache-store
- Model: notification
- Shorter cache timeout (1 minute)
- More frequent sync (30 seconds)
3. Customize the generated store:
```
```javascript
// Shorten cache validity
const CACHE_VALIDITY = 60 * 1000; // 1 minute
// More frequent sync
const SYNC_INTERVAL = 30 * 1000; // 30 seconds
// Add real-time refresh
export function enableRealTimeSync() {
return setInterval(() => {
refresh();
}, SYNC_INTERVAL);
}
```
---
## Example 7: Migrating Existing App 🔄
### Scenario:
Have an existing web app, want to add Odoo integration and offline functionality.
### Implementation Steps:
```
1. Generate reference implementation:
/new-svelte-pwa
- Project name: reference-app
- Model: your_model
2. Study generated code:
- Review odoo.js client
- Study cache.js pattern
- Examine API routes
3. Copy patterns to existing app:
- Copy src/lib/odoo.js
- Copy src/routes/api/odoo/+server.js
- Adapt cache store to your state management
4. Test integration:
/test-connection
5. Gradually add features:
- Start with read-only
- Add create functionality
- Add update/delete
- Add offline support
6. /deploy-vercel
```
---
## Common Customizations:
### 1. Add Search Functionality
```javascript
export function searchRecords(query) {
return $cache.filter(record =>
record.x_studio_name.toLowerCase().includes(query.toLowerCase())
);
}
```
### 2. Add Sorting
```javascript
export function sortBy(field, direction = 'asc') {
return $cache.sort((a, b) => {
const valA = a[field];
const valB = b[field];
return direction === 'asc' ? valA - valB : valB - valA;
});
}
```
### 3. Add Pagination
```javascript
export function paginate(page, pageSize) {
const start = (page - 1) * pageSize;
return $cache.slice(start, start + pageSize);
}
```
### 4. Add Export to CSV
```javascript
export function exportToCSV() {
const headers = ['ID', 'Name', 'Amount', 'Date'];
const rows = $cache.map(r => [
r.id,
r.x_studio_name,
r.x_studio_amount,
r.x_studio_date
]);
// Convert to CSV and download
}
```
### 5. Add Bulk Operations
```javascript
export async function bulkUpdate(ids, fields) {
const promises = ids.map(id => update(id, fields));
return Promise.all(promises);
}
```
---
## Tips for Success:
### Start Simple
1. Generate basic PWA first
2. Test with sample data
3. Add features incrementally
4. Deploy early and often
### Plan Your Models
1. Design Odoo model schema carefully
2. Include all necessary fields
3. Think about relationships
4. Consider mobile UX
### Test Thoroughly
1. Test offline functionality
2. Verify sync works correctly
3. Check error handling
4. Test on real devices
### Optimize Performance
1. Limit initial data load
2. Use pagination for large datasets
3. Lazy load images
4. Minimize bundle size
### Deploy Confidently
1. Test build locally
2. Use staging environment
3. Monitor errors
4. Have rollback plan
---
## Example prompts to use this command:
- `/examples` - Show all examples
- User: "Show me real-world examples"
- User: "How do I build an expense tracker?"
- User: "Give me ideas for using this plugin"
## Next Steps:
After reviewing these examples:
1. Choose a use case similar to your needs
2. Follow the implementation steps
3. Customize to match your requirements
4. Deploy and iterate
Need help? Run `/help` for more information!

596
commands/fix-sync.md Normal file
View File

@@ -0,0 +1,596 @@
Diagnose and fix synchronization issues between your PWA and Odoo.
## What this command does:
- Identifies sync problems
- Tests each component of the sync system
- Provides step-by-step fixes
- Clears problematic cached data
- Verifies sync works correctly
---
## Quick Diagnosis 🔍
Run through these quick checks first:
### 1. Visual Inspection
```
□ Check browser console for errors
□ Look at "Last synced" timestamp
□ Try manual refresh
□ Check network tab for failed requests
```
### 2. Quick Tests
```javascript
// In browser console:
// 1. Check if cache exists
localStorage.getItem('expenseCache');
// 2. Test API endpoint
fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'search',
model: 'res.partner',
domain: [],
fields: ['name'],
limit: 1
})
}).then(r => r.json()).then(console.log);
// 3. Force refresh
expenseCache.refresh();
```
### 3. Automatic Diagnosis
```bash
/test-connection
```
---
## Common Sync Issues
### Issue 1: Initial Load Works, But No Updates 🔄
**Symptoms:**
- Data loads on first visit
- But never updates with new Odoo data
- "Last synced" timestamp is old
- Background sync not happening
**Diagnosis:**
```javascript
// Check if sync timer is running
// In cache store, look for:
setInterval(() => syncInBackground(), 180000);
// Check if stale detection works
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
console.log('Last sync:', new Date(cacheData?.lastSyncTime));
console.log('Is stale?', Date.now() - cacheData?.lastSyncTime > 5 * 60 * 1000);
```
**Solutions:**
#### Solution A: Restart Background Sync
```javascript
// In browser console
expenseCache.stopAutoSync();
expenseCache.startAutoSync();
```
#### Solution B: Check Cache Validity
```javascript
// In cache store file (e.g., expenseCache.js)
const CACHE_VALIDITY = 5 * 60 * 1000; // 5 minutes
function isCacheStale() {
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
if (!cacheData) return true;
const now = Date.now();
const age = now - cacheData.lastSyncTime;
console.log(`Cache age: ${Math.floor(age / 1000)}s`);
return age > CACHE_VALIDITY;
}
```
#### Solution C: Force Manual Sync
```javascript
// Add a refresh button to your UI
<button onclick={() => expenseCache.refresh()}>
Sync Now
</button>
```
---
### Issue 2: Incremental Sync Not Working 📈
**Symptoms:**
- Always fetches all records
- Slow sync times
- High bandwidth usage
- `lastRecordId` not updating
**Diagnosis:**
```javascript
// Check lastRecordId
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
console.log('Last record ID:', cacheData?.lastRecordId);
// Check if it's being updated after sync
```
**Solutions:**
#### Solution A: Verify Domain Filter
```javascript
// In syncInBackground() function
async function syncInBackground() {
const { lastRecordId } = getCacheMetadata();
console.log('Fetching records with id >', lastRecordId);
const domain = lastRecordId > 0
? [['id', '>', lastRecordId]]
: [];
const newRecords = await odoo.searchRecords(
MODEL_NAME,
domain,
fields
);
console.log('Fetched:', newRecords.length, 'new records');
if (newRecords.length > 0) {
// Update lastRecordId
const maxId = Math.max(...newRecords.map(r => r.id));
updateCacheMetadata({ lastRecordId: maxId });
}
}
```
#### Solution B: Reset lastRecordId
```javascript
// If stuck, reset to fetch all
const cacheData = JSON.parse(localStorage.getItem('expenseCache'));
cacheData.lastRecordId = 0;
localStorage.setItem('expenseCache', JSON.stringify(cacheData));
// Then refresh
expenseCache.refresh();
```
---
### Issue 3: Optimistic Updates Not Syncing ⚡
**Symptoms:**
- Create/update works in UI
- But changes don't save to Odoo
- Records disappear on refresh
- Temp IDs persist
**Diagnosis:**
```javascript
// Check for temp IDs
console.log($expenseCache.filter(e => e.id.toString().startsWith('temp-')));
// Check browser console for API errors
```
**Solutions:**
#### Solution A: Check API Route
```javascript
// Test create
fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'create',
model: 'x_expense',
fields: {
x_studio_description: 'Test',
x_studio_amount: 10.00
}
})
})
.then(r => r.json())
.then(console.log)
.catch(console.error);
```
#### Solution B: Fix Error Handling
```javascript
// In cache store create() function
export async function create(data) {
const tempId = `temp-${Date.now()}`;
const tempRecord = { id: tempId, ...data };
// Add to cache
records.update(r => [...r, tempRecord]);
try {
// Create in Odoo
const realId = await odoo.createRecord(MODEL_NAME, data);
// Replace temp ID
records.update(r =>
r.map(rec => rec.id === tempId ? { ...rec, id: realId } : rec)
);
// Update cache metadata
await refresh(); // Sync to get the complete record
return realId;
} catch (error) {
console.error('Failed to create record:', error);
// Rollback
records.update(r => r.filter(rec => rec.id !== tempId));
// Re-throw
throw error;
}
}
```
#### Solution C: Clean Up Temp Records
```javascript
// Remove stuck temp records
expenseCache.records.update(records =>
records.filter(r => !r.id.toString().startsWith('temp-'))
);
// Then refresh
expenseCache.refresh();
```
---
### Issue 4: Partner Names Not Resolving 👥
**Symptoms:**
- Partner fields show IDs instead of names
- Many2one fields display as arrays
- "undefined" or "[object Object]" displayed
**Diagnosis:**
```javascript
// Check partner field format
const record = $expenseCache[0];
console.log('Employee field:', record.x_studio_employee);
// Should be: [12, "John Doe"] or 12
```
**Solutions:**
#### Solution A: Add Partner Resolution
```javascript
// In syncInBackground()
async function syncInBackground() {
// ... fetch records ...
// Resolve partner names
const partnerIds = new Set();
records.forEach(record => {
if (record.x_studio_employee) {
const id = Array.isArray(record.x_studio_employee)
? record.x_studio_employee[0]
: record.x_studio_employee;
partnerIds.add(id);
}
});
if (partnerIds.size > 0) {
const partners = await odoo.fetchPartners(Array.from(partnerIds));
const partnerMap = new Map(partners.map(p => [p.id, p.name]));
// Cache partners
localStorage.setItem('partnerCache', JSON.stringify(
Array.from(partnerMap.entries())
));
// Update records with names
records = records.map(record => {
if (record.x_studio_employee) {
const id = Array.isArray(record.x_studio_employee)
? record.x_studio_employee[0]
: record.x_studio_employee;
return {
...record,
x_studio_employee: [id, partnerMap.get(id) || 'Unknown']
};
}
return record;
});
}
}
```
#### Solution B: Display Helper Function
```javascript
// Helper to display partner name
function getPartnerName(field) {
if (!field) return 'None';
if (Array.isArray(field)) return field[1] || `ID: ${field[0]}`;
return `ID: ${field}`;
}
// In component
{getPartnerName(expense.x_studio_employee)}
```
---
### Issue 5: Duplicate Records 📋📋
**Symptoms:**
- Same record appears multiple times
- ID conflicts
- Sync creates duplicates
**Diagnosis:**
```javascript
// Check for duplicates
const ids = $expenseCache.map(r => r.id);
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
console.log('Duplicate IDs:', duplicates);
```
**Solutions:**
#### Solution A: Deduplicate Cache
```javascript
function deduplicateCache() {
records.update(currentRecords => {
const seen = new Set();
return currentRecords.filter(record => {
if (seen.has(record.id)) {
return false;
}
seen.add(record.id);
return true;
});
});
}
// Run deduplication
deduplicateCache();
```
#### Solution B: Fix Sync Logic
```javascript
// When appending new records, check for duplicates
async function appendToCache(newRecords) {
records.update(currentRecords => {
const existingIds = new Set(currentRecords.map(r => r.id));
// Only add records that don't exist
const toAdd = newRecords.filter(r => !existingIds.has(r.id));
return [...currentRecords, ...toAdd];
});
}
```
---
### Issue 6: Offline Queue Not Syncing 📴
**Symptoms:**
- Changes made offline
- Online now, but changes not syncing
- Stuck in "pending" state
**Solutions:**
#### Solution A: Implement Offline Queue
```javascript
// Store failed operations
const offlineQueue = writable([]);
async function queueOperation(operation) {
offlineQueue.update(q => [...q, operation]);
saveOfflineQueue();
}
async function processOfflineQueue() {
const queue = get(offlineQueue);
for (const operation of queue) {
try {
if (operation.type === 'create') {
await odoo.createRecord(operation.model, operation.data);
} else if (operation.type === 'update') {
await odoo.updateRecord(operation.model, operation.id, operation.data);
} else if (operation.type === 'delete') {
await odoo.deleteRecord(operation.model, operation.id);
}
// Remove from queue
offlineQueue.update(q => q.filter(op => op !== operation));
} catch (error) {
console.error('Failed to process queued operation:', error);
// Keep in queue, will retry
}
}
saveOfflineQueue();
}
// Listen for online event
window.addEventListener('online', () => {
console.log('Back online, processing queue...');
processOfflineQueue();
});
```
---
## Step-by-Step Fix Procedure 🔧
### Step 1: Clear Everything
```javascript
// Clear all caches
localStorage.clear();
// Clear IndexedDB
// DevTools → Application → IndexedDB → Delete database
```
### Step 2: Test API
```bash
/test-connection
```
### Step 3: Fresh Sync
```javascript
// Refresh page
location.reload();
// Should fetch all data fresh
```
### Step 4: Monitor Sync
```javascript
// Watch console for sync messages
// Should see:
// "Syncing x_expense..."
// "Fetched X records"
// "Cache updated"
```
### Step 5: Test CRUD
```javascript
// Test create
await expenseCache.create({ /* data */ });
// Test update
await expenseCache.update(id, { /* data */ });
// Test delete
await expenseCache.remove(id);
// Verify in Odoo
```
---
## Sync Debugging Checklist ✅
```
□ Browser console shows no errors
□ /api/odoo endpoint responds
□ ODOO_API_KEY is valid
□ lastSyncTime is updating
□ lastRecordId is updating
□ Background sync interval is running
□ Stale detection works correctly
□ Incremental fetch has correct domain
□ Optimistic updates resolve temp IDs
□ Partner names resolve correctly
□ No duplicate records
□ Offline queue processes when online
□ IndexedDB is storing data
□ localStorage has metadata
```
---
## Advanced Debugging 🐛
### Enable Verbose Logging
```javascript
// Add to cache store
const DEBUG = true;
function log(...args) {
if (DEBUG) console.log('[ExpenseCache]', ...args);
}
async function syncInBackground() {
log('Starting background sync...');
log('lastRecordId:', getLastRecordId());
const records = await fetch();
log('Fetched records:', records.length);
await saveToCache(records);
log('Cache updated');
}
```
### Monitor Network
```javascript
// Log all API calls
const originalFetch = window.fetch;
window.fetch = async (...args) => {
console.log('Fetch:', args[0]);
const response = await originalFetch(...args);
console.log('Response:', response.status);
return response;
};
```
### Profile Performance
```javascript
// Measure sync time
console.time('sync');
await expenseCache.refresh();
console.timeEnd('sync');
```
---
## Example prompts to use this command:
- `/fix-sync` - Diagnose sync issues
- User: "Data is not syncing"
- User: "My changes aren't saving"
- User: "Sync is broken"
## Related Commands:
- `/test-connection` - Test Odoo connectivity
- `/clear-cache` - Clear all cached data
- `/troubleshoot` - General troubleshooting
- `/help` - Full documentation
---
## Prevention Tips 🛡️
1. **Monitor sync health**
- Display "Last synced" timestamp in UI
- Show sync status indicator
- Alert on sync failures
2. **Handle errors gracefully**
- Catch and log all errors
- Show user-friendly messages
- Provide retry mechanisms
3. **Test offline scenarios**
- Test creating records offline
- Test going offline mid-sync
- Test coming back online
4. **Keep sync simple**
- Stick to generated patterns
- Don't overcomplicate logic
- Follow proven examples
5. **Regular maintenance**
- Clear old data periodically
- Update dependencies
- Monitor performance

322
commands/help.md Normal file
View File

@@ -0,0 +1,322 @@
Display comprehensive help and documentation for the Odoo PWA Generator plugin.
## What this command does:
- Provides overview of the plugin and its capabilities
- Lists all available commands with descriptions
- Explains the plugin's skills and when to use them
- Shows common usage patterns and workflows
- Links to detailed documentation
## Plugin Overview:
The **odoo-pwa-generator** plugin helps you create offline-first Progressive Web Apps with Odoo Studio backend integration. It supports SvelteKit, React, and Vue frameworks.
### Key Features:
**Quick Project Generation** - Create complete PWAs in minutes
📱 **Offline-First** - Smart caching with background sync
🔄 **Odoo Integration** - Seamless Odoo Studio connectivity
🚀 **Production Ready** - Pre-configured deployment setups
**Framework Support** - SvelteKit, React, and Vue
### Core Capabilities:
- Automatic CRUD operations for Odoo models
- Smart caching with localStorage + IndexedDB
- Incremental sync (only fetch new records)
- Optimistic UI updates
- Partner/relation resolution
- PWA installability
- Offline functionality
## Available Commands:
### 🎯 Skill Shortcuts (Project Generation)
Create new PWA projects:
- `/new-svelte-pwa` - Generate SvelteKit PWA
- `/new-react-pwa` - Generate React PWA
- `/new-vue-pwa` - Generate Vue PWA
- `/add-model` - Add Odoo model to existing PWA
- `/create-cache-store` - Create cache store for a model
### 🔧 Workflow Commands
Development and deployment:
- `/init-project` - Initialize new PWA project
- `/setup-env` - Configure environment variables
- `/test-connection` - Test Odoo API connection
- `/deploy-vercel` - Deploy to Vercel
- `/deploy-github` - Deploy to GitHub Pages
### 📚 Documentation Commands
Help and reference:
- `/help` - This help document (you are here!)
- `/examples` - Real-world usage examples
- `/architecture` - Explain PWA architecture
- `/api-reference` - Odoo API client documentation
- `/troubleshoot` - Common issues and solutions
### 🛠 Maintenance Commands
Project management:
- `/update-deps` - Update project dependencies
- `/fix-sync` - Diagnose and fix sync issues
- `/clear-cache` - Clear application caches
- `/add-deployment` - Add new deployment target
- `/optimize` - Run optimization checks
## Common Workflows:
### 1⃣ Starting a New Project
```
1. /new-svelte-pwa (or /new-react-pwa or /new-vue-pwa)
2. Provide project details (name, model, etc.)
3. /init-project
4. Start coding!
```
### 2⃣ Setting Up Environment
```
1. /setup-env
2. Provide Odoo credentials
3. /test-connection
4. Verify everything works
```
### 3⃣ Adding More Models
```
1. /add-model
2. Specify model name and details
3. Test CRUD operations
4. Customize UI as needed
```
### 4⃣ Deploying to Production
```
1. /deploy-vercel (recommended)
OR /deploy-github
2. Configure environment variables
3. Test deployed application
4. Set up custom domain (optional)
```
### 5⃣ Troubleshooting Issues
```
1. /test-connection - Check Odoo connectivity
2. /troubleshoot - Find specific solutions
3. /fix-sync - Diagnose sync problems
4. /clear-cache - Reset if needed
```
## Quick Start Guide:
### Step 1: Generate a New PWA
Choose your framework and run the appropriate command:
```
/new-svelte-pwa
```
### Step 2: Provide Project Details
When prompted, provide:
- **Project name**: e.g., "expense-tracker"
- **Odoo model**: e.g., "expense" (without x_ prefix)
- **Display name**: e.g., "Expense"
- **Deployment target**: e.g., "vercel" (optional)
### Step 3: Initialize the Project
```
cd your-project-name
/init-project
```
### Step 4: Configure Odoo Connection
```
/setup-env
```
Provide your Odoo URL, database, API key, and username.
### Step 5: Test Everything
```
/test-connection
```
Verify your Odoo connection works correctly.
### Step 6: Start Developing
The dev server should be running. Open your browser and start customizing!
### Step 7: Deploy (when ready)
```
/deploy-vercel
```
Follow the prompts to deploy to production.
## Plugin Skills:
### create-odoo-pwa
Generates a complete PWA project from scratch.
**When to use**: Starting a new project
**What it generates**:
- Base configuration (package.json, vite.config, etc.)
- Odoo API client
- Cache stores with smart syncing
- Server-side API proxy
- UI components (forms, lists)
- PWA manifest and service worker
- Deployment configurations
- Complete documentation
### add-odoo-model
Adds integration for additional Odoo models.
**When to use**: Adding new data models to existing project
**What it generates**:
- Cache store for the new model
- API methods in Odoo client
- Form and list pages (optional)
- Navigation updates
### create-cache-store
Creates a standalone cache store.
**When to use**: Need custom caching logic
**What it generates**:
- Framework-specific cache store
- Smart caching logic
- Background sync
- Optimistic updates
## Best Practices:
### Security
- ✅ Keep API keys in `.env` file (never commit)
- ✅ Use different credentials for dev and production
- ✅ Set environment variables in hosting platform
- ✅ Rotate API keys periodically
### Development
- ✅ Test Odoo connection before coding
- ✅ Use version control (Git)
- ✅ Test offline functionality regularly
- ✅ Read generated CLAUDE.md for patterns
### Deployment
- ✅ Build and test locally first
- ✅ Use Vercel/Netlify for full functionality
- ✅ Set up continuous deployment from Git
- ✅ Monitor performance and errors
### Maintenance
- ✅ Keep dependencies updated
- ✅ Monitor Odoo API changes
- ✅ Test after Odoo upgrades
- ✅ Clear caches when schema changes
## Getting More Help:
### Example prompts to use this command:
- `/help` - Show this help document
- User: "How do I use the Odoo PWA plugin?"
- User: "What commands are available?"
### In Generated Projects:
- `README.md` - Getting started guide
- `CLAUDE.md` - Architecture patterns
- `API.md` - API client reference
### External Resources:
- Odoo API Documentation: https://www.odoo.com/documentation/
- SvelteKit: https://kit.svelte.dev/
- React: https://react.dev/
- Vue: https://vuejs.org/
- PWA Guide: https://web.dev/progressive-web-apps/
### Troubleshooting:
If you encounter issues:
1. Run `/test-connection` to diagnose
2. Check `/troubleshoot` for common solutions
3. Review browser console for errors
4. Verify Odoo configuration
5. Check generated documentation
### Support:
For bugs or feature requests:
- Check existing issues
- Review documentation thoroughly
- Provide detailed error messages
- Include environment details
## Framework-Specific Notes:
### SvelteKit (Recommended)
- Uses Svelte 5 runes syntax
- Server-side API routes work perfectly
- Best offline functionality
- Smallest bundle size
- Easiest to deploy
### React
- Modern React 18+ hooks
- Context API for state management
- Wide ecosystem support
- Popular and familiar
### Vue
- Vue 3 Composition API
- Pinia for state management
- Great developer experience
- Progressive framework
## Architecture Highlights:
### Data Flow
```
Component → Cache Store → API Client → Server Route → Odoo
```
### Caching Strategy
1. **Load from cache** (instant, may be stale)
2. **Check if stale** (> 5 minutes)
3. **Background sync** (fetch new data)
4. **Update cache** (localStorage + IndexedDB)
5. **Reactive update** (UI updates automatically)
### Sync Strategy
1. **Incremental fetch** - Only `id > lastRecordId`
2. **Partner resolution** - Batch fetch related records
3. **Optimistic updates** - UI updates before server
4. **Error recovery** - Graceful offline handling
## Tips and Tricks:
💡 **Use the right command for the job**
- Quick start? `/new-svelte-pwa`
- Need help? `/help` or `/troubleshoot`
- Deploy ready? `/deploy-vercel`
💡 **Test early and often**
- Run `/test-connection` after setup
- Test offline mode frequently
- Verify sync works correctly
💡 **Read the generated docs**
- CLAUDE.md has architecture details
- API.md has client method docs
- README.md has setup instructions
💡 **Customize to your needs**
- Start with generated code
- Modify UI components
- Add business logic
- Extend with new features
💡 **Deploy with confidence**
- Test build locally first
- Use environment variables properly
- Monitor after deployment
- Set up error tracking
## Summary:
The odoo-pwa-generator plugin makes it easy to create production-ready PWAs with Odoo integration. Use the commands above to generate, develop, deploy, and maintain your applications.
For more details on any command, just run that command and follow the prompts!
Happy coding! 🚀

202
commands/init-project.md Normal file
View File

@@ -0,0 +1,202 @@
Initialize a newly generated Odoo PWA project with all necessary setup steps.
## What this command does:
- Runs `npm install` to install all dependencies
- Creates `.env` file from `.env.example`
- Guides through environment configuration
- Tests the Odoo connection
- Starts the development server
- Opens the application in browser
- Provides next steps and documentation
## Prerequisites:
- Newly generated Odoo PWA project
- Node.js installed (v18 or higher)
- npm or pnpm package manager
- Internet connection for dependencies
## Steps:
### 1. Verify Project Structure
Check that required files exist:
-`package.json`
-`.env.example`
-`README.md`
-`src/lib/odoo.js` (or equivalent)
- ✅ Framework config file (svelte.config.js / vite.config.js)
### 2. Install Dependencies
```bash
npm install
```
Show progress and estimated time.
### 3. Environment Setup
Copy `.env.example` to `.env`:
```bash
cp .env.example .env
```
Ask the user to provide:
1. Odoo URL
2. Database name
3. API key
4. Username
5. Model configuration
Update `.env` file with provided values.
### 4. Verify Setup
Read `.env` and verify all required variables are set.
### 5. Test Odoo Connection
Run a quick connection test:
- Test authentication
- Verify model access
- Check permissions
If connection fails, offer to run full diagnostics (`/test-connection`).
### 6. Initialize Git (if not already)
```bash
git init
git add .
git commit -m "Initial commit: Odoo PWA generated"
```
### 7. Start Development Server
```bash
npm run dev
```
Framework-specific commands:
- **SvelteKit**: `npm run dev` (default port 5173)
- **React**: `npm run dev` (default port 5173)
- **Vue**: `npm run dev` (default port 5173)
### 8. Open in Browser
Automatically open browser to `http://localhost:5173`
## Example prompts to use this command:
- `/init-project` - Complete initialization wizard
- User: "Set up my new Odoo PWA"
- User: "Initialize the project"
- User: "Get my PWA running"
## Post-Initialization Checklist:
After successful initialization:
**Immediate Next Steps**:
1. Test the application in the browser
2. Verify data loads from Odoo
3. Test creating a new record
4. Test editing and deleting records
5. Verify offline functionality (disable network)
**Configuration**:
1. Review and customize PWA manifest (colors, icons, name)
2. Update application metadata
3. Configure deployment targets
4. Set up version control (Git)
**Development**:
1. Read the generated `CLAUDE.md` for architecture details
2. Review `API.md` for Odoo client documentation
3. Explore the codebase structure
4. Customize UI components and styling
**Testing**:
1. Test all CRUD operations
2. Verify sync functionality
3. Test offline mode
4. Check PWA installability
5. Test on mobile devices
**Deployment Preparation**:
1. Review deployment documentation
2. Set up hosting platform account (Vercel/Netlify/etc)
3. Prepare production Odoo API keys
4. Configure environment variables for production
## Helpful Resources:
Provide links to:
- Project `README.md`
- `CLAUDE.md` (architecture guide)
- `API.md` (API documentation)
- Odoo documentation
- Framework documentation (SvelteKit/React/Vue)
- PWA best practices
## Development Commands:
Remind the user of available commands:
```bash
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run linter
npm run format # Format code
```
## Troubleshooting:
### npm install fails
- Check Node.js version (must be v18+)
- Clear npm cache: `npm cache clean --force`
- Delete `node_modules` and `package-lock.json`, try again
- Check internet connection
### .env configuration issues
- Verify all variables are set (no empty values)
- Check for typos in variable names
- Ensure no spaces around `=` signs
- Verify Odoo credentials are correct
### Development server won't start
- Check if port 5173 is already in use
- Try different port: `npm run dev -- --port 3000`
- Check for syntax errors in config files
- Review console error messages
### Odoo connection fails
- Run `/test-connection` for full diagnostics
- Verify `.env` file is loaded correctly
- Check Odoo server is accessible
- Verify API key is valid
### Build fails
- Check for TypeScript errors (if using TypeScript)
- Verify all dependencies are installed
- Check for missing environment variables
- Review build logs for specific errors
## After Initialization:
Display summary:
```
🎉 Odoo PWA Initialized Successfully!
📁 Project: [project-name]
🚀 Framework: [SvelteKit/React/Vue]
🔗 Dev Server: http://localhost:5173
📝 Model: [model-name]
✅ Next Steps:
1. Open http://localhost:5173 in your browser
2. Test data sync from Odoo
3. Read CLAUDE.md for architecture details
4. Customize the UI to match your needs
5. Run /deploy-vercel when ready to deploy
📚 Documentation:
- README.md - Getting started guide
- CLAUDE.md - Architecture and patterns
- API.md - Odoo API client reference
💡 Helpful Commands:
- /test-connection - Verify Odoo integration
- /add-model - Add more Odoo models
- /deploy-vercel - Deploy to production
- /odoo-help - Get plugin help
Happy coding! 🚀
```

33
commands/new-react-pwa.md Normal file
View File

@@ -0,0 +1,33 @@
Generate a new offline-first Progressive Web App using React framework with Odoo Studio backend integration.
## What this command does:
- Invokes the `create-odoo-pwa` skill with React as the framework
- Generates a complete PWA project with smart caching, offline support, and Odoo integration
- Creates all necessary configuration files, components, hooks, and deployment setups
## Required Information:
Before starting, gather:
1. **Project name** (kebab-case, e.g., "expense-tracker", "inventory-manager")
2. **Odoo model name** (without `x_` prefix, e.g., "expense", "inventory")
3. **Model display name** (human-readable, e.g., "Expense", "Inventory Item")
4. **Deployment target** (optional: vercel, github, cloudflare, netlify)
## Steps:
1. Ask the user for the required information listed above
2. Invoke the `create-odoo-pwa` skill with framework set to "react"
3. Generate the complete React PWA project structure
4. Create comprehensive documentation (README.md, CLAUDE.md, API.md)
5. Provide next steps for setup and deployment
## Example prompts to use this command:
- `/new-react-pwa` - Interactive mode, will ask for all parameters
- User: "Create a React PWA for tracking expenses with Odoo"
- User: "Generate an inventory management app using React and Odoo Studio"
## After generation:
Remind the user to:
1. Navigate to the project directory
2. Copy `.env.example` to `.env` and configure Odoo credentials
3. Run `npm install` to install dependencies
4. Run `npm run dev` to start development server
5. Test the Odoo connection and sync functionality

View File

@@ -0,0 +1,33 @@
Generate a new offline-first Progressive Web App using SvelteKit framework with Odoo Studio backend integration.
## What this command does:
- Invokes the `create-odoo-pwa` skill with SvelteKit as the framework
- Generates a complete PWA project with smart caching, offline support, and Odoo integration
- Creates all necessary configuration files, routes, components, and deployment setups
## Required Information:
Before starting, gather:
1. **Project name** (kebab-case, e.g., "expense-tracker", "inventory-manager")
2. **Odoo model name** (without `x_` prefix, e.g., "expense", "inventory")
3. **Model display name** (human-readable, e.g., "Expense", "Inventory Item")
4. **Deployment target** (optional: vercel, github, cloudflare, netlify)
## Steps:
1. Ask the user for the required information listed above
2. Invoke the `create-odoo-pwa` skill with framework set to "sveltekit"
3. Generate the complete SvelteKit PWA project structure
4. Create comprehensive documentation (README.md, CLAUDE.md, API.md)
5. Provide next steps for setup and deployment
## Example prompts to use this command:
- `/new-svelte-pwa` - Interactive mode, will ask for all parameters
- User: "Create a SvelteKit PWA for tracking expenses with Odoo"
- User: "Generate an inventory management app using SvelteKit and Odoo Studio"
## After generation:
Remind the user to:
1. Navigate to the project directory
2. Copy `.env.example` to `.env` and configure Odoo credentials
3. Run `npm install` to install dependencies
4. Run `npm run dev` to start development server
5. Test the Odoo connection and sync functionality

33
commands/new-vue-pwa.md Normal file
View File

@@ -0,0 +1,33 @@
Generate a new offline-first Progressive Web App using Vue framework with Odoo Studio backend integration.
## What this command does:
- Invokes the `create-odoo-pwa` skill with Vue as the framework
- Generates a complete PWA project with smart caching, offline support, and Odoo integration
- Creates all necessary configuration files, components, composables, and deployment setups
## Required Information:
Before starting, gather:
1. **Project name** (kebab-case, e.g., "expense-tracker", "inventory-manager")
2. **Odoo model name** (without `x_` prefix, e.g., "expense", "inventory")
3. **Model display name** (human-readable, e.g., "Expense", "Inventory Item")
4. **Deployment target** (optional: vercel, github, cloudflare, netlify)
## Steps:
1. Ask the user for the required information listed above
2. Invoke the `create-odoo-pwa` skill with framework set to "vue"
3. Generate the complete Vue PWA project structure
4. Create comprehensive documentation (README.md, CLAUDE.md, API.md)
5. Provide next steps for setup and deployment
## Example prompts to use this command:
- `/new-vue-pwa` - Interactive mode, will ask for all parameters
- User: "Create a Vue PWA for tracking expenses with Odoo"
- User: "Generate an inventory management app using Vue and Odoo Studio"
## After generation:
Remind the user to:
1. Navigate to the project directory
2. Copy `.env.example` to `.env` and configure Odoo credentials
3. Run `npm install` to install dependencies
4. Run `npm run dev` to start development server
5. Test the Odoo connection and sync functionality

642
commands/optimize.md Normal file
View File

@@ -0,0 +1,642 @@
Analyze and optimize your Odoo PWA for performance, bundle size, and user experience.
## What this command does:
- Analyzes bundle size
- Identifies performance bottlenecks
- Suggests optimizations
- Checks caching efficiency
- Reviews PWA configuration
- Provides actionable recommendations
---
## Quick Performance Check 🚀
### Run These Commands:
```bash
# Build for production
npm run build
# Analyze bundle size
npm run build -- --analyze
# Preview production build
npm run preview
# Run Lighthouse audit
# (Chrome DevTools → Lighthouse tab)
```
---
## Bundle Size Analysis 📦
### Check Current Size
```bash
# Build and see output
npm run build
# Typical output:
# dist/index.html 1.2 kB
# dist/assets/index-abc123.js 45.3 kB
# dist/assets/vendor-def456.js 120.5 kB
```
### Analyze Bundle Composition
```bash
# Install analyzer
npm install -D rollup-plugin-visualizer
# Add to vite.config.js
import { visualizer } from 'rollup-plugin-visualizer';
export default {
plugins: [
// ...other plugins
visualizer({
open: true,
gzipSize: true,
brotliSize: true
})
]
};
# Build and open report
npm run build
# Opens stats.html in browser
```
### Target Bundle Sizes:
-**Excellent**: < 200 KB (gzipped)
- ⚠️ **Good**: 200-500 KB
-**Needs Work**: > 500 KB
---
## Optimization Strategies
### 1. Code Splitting 📂
#### Lazy Load Routes
**SvelteKit** (automatic):
```javascript
// Routes are auto-split
// src/routes/+page.svelte → separate chunk
```
**React**:
```javascript
import { lazy, Suspense } from 'react';
const ExpenseList = lazy(() => import('./ExpenseList'));
function App() {
return (
<Suspense fallback={<Loading />}>
<ExpenseList />
</Suspense>
);
}
```
**Vue**:
```javascript
const ExpenseList = () => import('./ExpenseList.vue');
const routes = [
{
path: '/expenses',
component: ExpenseList // Lazy loaded
}
];
```
#### Manual Code Splitting
```javascript
// Split heavy utility into separate chunk
const heavyUtil = await import('./heavyUtility.js');
heavyUtil.doSomething();
```
### 2. Tree Shaking 🌳
#### Remove Unused Code
```javascript
// Bad: Imports everything
import * as utils from './utils';
// Good: Import only what you need
import { formatDate, formatCurrency } from './utils';
```
#### Check for Unused Dependencies
```bash
npm install -g depcheck
depcheck
# Remove unused packages
npm uninstall <unused-package>
```
### 3. Optimize Dependencies 📚
#### Use Lighter Alternatives
```javascript
// Instead of moment.js (heavy)
import moment from 'moment'; // 72 KB
// Use date-fns (tree-shakeable)
import { format } from 'date-fns'; // ~2 KB
// Or native Date
new Date().toLocaleDateString();
```
#### Common Heavy Packages & Alternatives:
-**moment** (72 KB) → ✅ **date-fns** (tree-shakeable)
-**lodash** (whole) → ✅ **lodash-es** (individual imports)
-**axios** → ✅ **fetch** (built-in)
-**uuid** → ✅ **crypto.randomUUID()** (built-in)
### 4. Optimize Images 🖼️
#### Compress Images
```bash
# Install image optimizer
npm install -D vite-plugin-imagemin
# Add to vite.config.js
import viteImagemin from 'vite-plugin-imagemin';
export default {
plugins: [
viteImagemin({
gifsicle: { optimizationLevel: 7 },
optipng: { optimizationLevel: 7 },
mozjpeg: { quality: 80 },
svgo: { plugins: [{ removeViewBox: false }] }
})
]
};
```
#### Lazy Load Images
```javascript
// Native lazy loading
<img src="large-image.jpg" loading="lazy" />
// Or with IntersectionObserver
```
#### Use Appropriate Formats
- **WebP** for photos (smaller than JPEG)
- **SVG** for icons/logos
- **PNG** only when transparency needed
### 5. Minimize JavaScript ⚡
#### Enable Minification (default in Vite)
```javascript
// vite.config.js
export default {
build: {
minify: 'terser', // or 'esbuild' (faster)
terserOptions: {
compress: {
drop_console: true, // Remove console.logs
drop_debugger: true
}
}
}
};
```
#### Remove Development Code
```javascript
// Use environment variables
if (import.meta.env.DEV) {
console.log('Debug info'); // Removed in production
}
```
---
## Caching Optimization 💾
### 1. Optimize Cache Strategy
#### Review Cache Settings
```javascript
// In cache store
const CACHE_VALIDITY = 5 * 60 * 1000; // 5 minutes
// Consider your use case:
// - Frequently changing data: 1-2 minutes
// - Moderate updates: 5-10 minutes
// - Rarely changes: 30-60 minutes
```
#### Limit Initial Load
```javascript
// Don't fetch everything at once
const records = await odoo.searchRecords(
model,
[],
fields,
100 // Limit to 100 records initially
);
// Load more on demand (pagination)
```
### 2. Optimize Sync Frequency
```javascript
// Adjust sync interval based on needs
const SYNC_INTERVAL = 5 * 60 * 1000; // 5 minutes
// Balance:
// - More frequent: Better UX, more bandwidth
// - Less frequent: Less bandwidth, slightly stale data
```
### 3. Selective Caching
```javascript
// Only cache fields you need
const fields = [
'x_studio_name',
'x_studio_amount',
'x_studio_date'
// Don't fetch unnecessary fields
];
```
---
## PWA Optimization 📱
### 1. Service Worker Configuration
#### Optimize Caching Strategy
```javascript
// In service worker or vite-plugin-pwa config
VitePWA({
workbox: {
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year
}
}
},
{
urlPattern: /^https:\/\/.*\.odoo\.com\/.*/,
handler: 'NetworkFirst',
options: {
cacheName: 'odoo-api',
networkTimeoutSeconds: 3
}
}
]
}
})
```
### 2. Optimize Manifest
```json
{
"name": "Expense Tracker",
"short_name": "Expenses",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0066cc",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
```
### 3. Optimize Icons
```bash
# Use optimized PNG or WebP
# Compress images
# Provide multiple sizes
```
---
## Network Optimization 🌐
### 1. Reduce API Calls
#### Batch Requests
```javascript
// Bad: Multiple calls
const expenses = await fetchExpenses();
const tasks = await fetchTasks();
const partners = await fetchPartners();
// Good: Single call (if Odoo supports)
const data = await fetchAll(['expenses', 'tasks', 'partners']);
```
#### Cache Partner Names
```javascript
// Fetch once, reuse
const partners = await odoo.fetchPartners();
localStorage.setItem('partnerCache', JSON.stringify(partners));
// Later, use cached data
const cached = JSON.parse(localStorage.getItem('partnerCache'));
```
### 2. Incremental Loading
```javascript
// Load initial data
const initial = await fetchExpenses({ limit: 20 });
// Load more on scroll
function onScroll() {
if (nearBottom) {
loadMore();
}
}
```
### 3. Optimize Requests
```javascript
// Only fetch fields you display
const fields = ['id', 'x_studio_name', 'x_studio_amount'];
// Use appropriate domain filters
const domain = [
['x_studio_date', '>=', lastMonth],
['x_studio_status', '!=', 'deleted']
];
```
---
## UI Performance 🎨
### 1. Virtual Scrolling
For long lists:
```javascript
// SvelteKit
import { VirtualList } from 'svelte-virtual-list';
<VirtualList items={expenses} let:item>
<ExpenseCard expense={item} />
</VirtualList>
// React
import { FixedSizeList } from 'react-window';
// Vue
import { RecycleScroller } from 'vue-virtual-scroller';
```
### 2. Debounce Search
```javascript
import { debounce } from './utils';
const handleSearch = debounce((query) => {
searchExpenses(query);
}, 300); // Wait 300ms after typing stops
```
### 3. Optimize Rendering
```javascript
// SvelteKit: Use keyed each blocks
{#each expenses as expense (expense.id)}
<ExpenseCard {expense} />
{/each}
// React: Use keys and memo
const ExpenseCard = memo(({ expense }) => {
// ...
});
expenses.map(expense => (
<ExpenseCard key={expense.id} expense={expense} />
));
// Vue: Use v-memo
<ExpenseCard
v-for="expense in expenses"
:key="expense.id"
:expense="expense"
v-memo="[expense.id]"
/>
```
---
## Build Optimization 🔨
### Vite Config Optimizations
```javascript
// vite.config.js
export default {
build: {
// Target modern browsers
target: 'es2020',
// Optimize chunks
rollupOptions: {
output: {
manualChunks: {
vendor: ['svelte', '@sveltejs/kit'],
odoo: ['./src/lib/odoo.js', './src/lib/stores']
}
}
},
// Compression
minify: 'esbuild', // Faster than terser
// Source maps (only for debugging)
sourcemap: false
},
// Optimize dependencies
optimizeDeps: {
include: ['date-fns', 'lodash-es']
}
};
```
---
## Lighthouse Audit 💡
### Run Lighthouse
1. Open Chrome DevTools
2. Go to Lighthouse tab
3. Select categories:
- ✅ Performance
- ✅ Progressive Web App
- ✅ Best Practices
- ✅ Accessibility
- ✅ SEO
4. Click "Analyze page load"
### Target Scores:
- **Performance**: > 90
- **PWA**: 100
- **Best Practices**: > 95
- **Accessibility**: > 90
- **SEO**: > 90
### Common Issues & Fixes:
#### Low Performance Score
- Reduce bundle size
- Optimize images
- Enable caching
- Lazy load resources
#### PWA Issues
- Fix manifest.json
- Register service worker
- Add offline support
- Provide app icons
#### Accessibility Issues
- Add alt text to images
- Use semantic HTML
- Ensure color contrast
- Add ARIA labels
---
## Performance Monitoring 📊
### Add Performance Tracking
```javascript
// Measure initial load
window.addEventListener('load', () => {
const perfData = performance.getEntriesByType('navigation')[0];
console.log('Load time:', perfData.loadEventEnd - perfData.fetchStart);
console.log('DOM ready:', perfData.domContentLoadedEventEnd - perfData.fetchStart);
});
// Measure sync time
console.time('sync');
await expenseCache.refresh();
console.timeEnd('sync');
```
### Use Web Vitals
```bash
npm install web-vitals
# In app
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getFCP(console.log);
getLCP(console.log);
getTTFB(console.log);
```
---
## Optimization Checklist ✅
### Bundle Size:
```
□ Analyzed bundle composition
□ Removed unused dependencies
□ Lazy loaded routes/components
□ Optimized images
□ Tree-shaking enabled
□ Minification enabled
□ Total size < 500 KB (gzipped)
```
### Caching:
```
□ Optimal cache validity period
□ Incremental sync working
□ Selective field fetching
□ Partner name caching
□ Appropriate sync frequency
□ IndexedDB optimized
```
### PWA:
```
□ Service worker registered
□ Offline mode works
□ App installable
□ Icons optimized
□ Manifest configured
□ Fast load time
```
### Performance:
```
□ Lighthouse score > 90
□ Initial load < 3s
□ Sync time < 2s
□ No console errors
□ Smooth scrolling
□ Fast navigation
```
---
## Example prompts to use this command:
- `/optimize` - Run optimization checks
- User: "Make my app faster"
- User: "Reduce bundle size"
- User: "Optimize performance"
## Related Commands:
- `/test-connection` - Test after optimization
- `/update-deps` - Update to faster versions
- `/troubleshoot` - Fix performance issues
- `/help` - More information
---
## Quick Wins 🎯
### Immediate Optimizations:
1. **Enable compression** (already in Vite)
2. **Remove console.logs** in production
3. **Lazy load routes** (easy with frameworks)
4. **Optimize images** (use WebP)
5. **Limit initial data fetch** (pagination)
### Medium Effort:
1. **Analyze and split bundles**
2. **Replace heavy dependencies**
3. **Implement virtual scrolling**
4. **Optimize service worker**
5. **Add performance monitoring**
### Long Term:
1. **Regular Lighthouse audits**
2. **Monitor real user metrics**
3. **Continuous optimization**
4. **Keep dependencies updated**
5. **Review and refactor regularly**

87
commands/setup-env.md Normal file
View File

@@ -0,0 +1,87 @@
Interactive setup wizard for configuring Odoo PWA environment variables.
## What this command does:
- Guides the user through setting up their `.env` file
- Validates Odoo connection credentials
- Tests API connectivity
- Configures model-specific settings
- Provides troubleshooting help if connection fails
## Required Information:
Gather from the user:
1. **Odoo Instance URL** (e.g., "https://yourcompany.odoo.com")
2. **Database Name** (e.g., "yourcompany-main")
3. **API Key** (from Odoo user preferences)
4. **Username/Email** (Odoo user email)
5. **Primary Model Name** (e.g., "x_expense", "x_inventory")
## Steps:
1. Check if `.env.example` exists in the current directory
2. If not, ask if this is an Odoo PWA project
3. Ask the user for each environment variable interactively
4. Validate URL format (must start with http:// or https://)
5. Create or update `.env` file with the provided values
6. Test the connection by making a simple API call to Odoo
7. If connection fails, provide troubleshooting steps
8. Display success message with next steps
## Environment Variables to Set:
```bash
# Odoo Instance Configuration
VITE_ODOO_URL=https://yourcompany.odoo.com
VITE_ODOO_DB=yourcompany-main
# Authentication (keep these secret!)
ODOO_API_KEY=your_api_key_here
ODOO_USERNAME=your.email@company.com
# Model Configuration
VITE_MODEL_NAME=x_expense
VITE_MODEL_DISPLAY_NAME=Expense
```
## Validation Tests:
After creating `.env`, run these checks:
1. Test Odoo URL is reachable
2. Verify API key is valid
3. Check if the model exists in Odoo
4. Test read permissions on the model
5. Verify required fields are accessible
## Example prompts to use this command:
- `/setup-env` - Interactive setup wizard
- User: "Help me configure my Odoo credentials"
- User: "Set up environment variables for Odoo PWA"
## Security Reminders:
After setup, remind the user:
1.`.env` should be in `.gitignore` (verify this)
2. ✅ Never commit API keys to version control
3. ✅ Use different credentials for development and production
4. ✅ For deployment, set environment variables in the hosting platform
5. ✅ Rotate API keys periodically
## Troubleshooting Common Issues:
### Connection Failed
- Verify Odoo URL is correct and accessible
- Check if API key is valid (generate new one in Odoo)
- Ensure username matches the API key owner
- Check firewall/network restrictions
### Model Not Found
- Verify the model exists in Odoo Studio
- Check model name has `x_` prefix
- Ensure user has access permissions to the model
### Authentication Error
- Regenerate API key in Odoo (Settings → Users → API Keys)
- Verify database name is correct
- Check if account is active and not locked
## After Setup:
Remind the user to:
1. Restart the development server to load new environment variables
2. Test the application and verify data loads correctly
3. Keep the `.env.example` file updated for team members
4. Document any custom configuration in project README

230
commands/test-connection.md Normal file
View File

@@ -0,0 +1,230 @@
Test Odoo API connection and sync functionality to diagnose issues.
## What this command does:
- Validates Odoo connection credentials
- Tests API authentication
- Verifies model access and permissions
- Checks sync functionality
- Runs diagnostic tests on cache stores
- Provides detailed error reporting and solutions
## Prerequisites:
Before testing, ensure:
1.`.env` file exists and is configured
2. ✅ Current directory is an Odoo PWA project
3. ✅ Development server can be started
4. ✅ Internet connection is available
## Diagnostic Tests to Run:
### 1. Environment Configuration Check
Verify all required environment variables are set:
- `VITE_ODOO_URL` - Odoo instance URL
- `VITE_ODOO_DB` - Database name
- `ODOO_API_KEY` - API authentication key
- `ODOO_USERNAME` - User email/username
- `VITE_MODEL_NAME` - Primary model name
### 2. Network Connectivity Test
```bash
# Test if Odoo URL is reachable
curl -I [ODOO_URL]
```
Expected: HTTP 200 or 301/302 redirect
### 3. API Authentication Test
Make a test API call to verify credentials:
```javascript
POST /api/odoo
{
"action": "search",
"model": "res.partner",
"domain": [],
"fields": ["id", "name"],
"limit": 1
}
```
Expected: Returns at least one partner record
### 4. Model Access Test
Verify the configured model exists and is accessible:
```javascript
POST /api/odoo
{
"action": "search_model",
"model": "[VITE_MODEL_NAME]",
"domain": [],
"fields": ["id"],
"limit": 1
}
```
Expected: Returns records or empty array (not an error)
### 5. CRUD Operations Test
Test each operation:
- **Create**: Create a test record
- **Read**: Fetch the created record
- **Update**: Modify the record
- **Delete**: Remove the test record
### 6. Cache Functionality Test
Verify cache stores work correctly:
- localStorage read/write
- IndexedDB read/write
- Cache expiration logic
- Sync mechanism
### 7. Sync Performance Test
Measure sync performance:
- Initial load time
- Incremental sync time
- Number of records synced
- Network request count
## Steps:
1. Read and validate `.env` file
2. Parse environment variables
3. Run each diagnostic test in sequence
4. Log results with timestamps
5. Identify failing tests
6. Provide specific solutions for failures
7. Generate diagnostic report
## Output Format:
```
🧪 Odoo PWA Connection Diagnostics
================================
✅ Environment Configuration: PASSED
- ODOO_URL: https://yourcompany.odoo.com
- DATABASE: yourcompany-main
- MODEL: x_expense
✅ Network Connectivity: PASSED
- Odoo server reachable
- Response time: 234ms
✅ API Authentication: PASSED
- API key valid
- User authenticated: your.email@company.com
✅ Model Access: PASSED
- Model exists: x_expense
- Read permission: Yes
- Write permission: Yes
✅ CRUD Operations: PASSED
- Create: ✅ Record created (ID: 123)
- Read: ✅ Record fetched
- Update: ✅ Record updated
- Delete: ✅ Record deleted
✅ Cache Functionality: PASSED
- localStorage: Working
- IndexedDB: Working
- Sync interval: 3 minutes
✅ Sync Performance: PASSED
- Initial load: 1.2s (45 records)
- Incremental sync: 0.3s (2 new records)
- Network requests: 3
================================
🎉 All tests passed! Your Odoo PWA is working correctly.
```
## Example prompts to use this command:
- `/test-connection` - Run full diagnostic suite
- User: "Test my Odoo connection"
- User: "Why isn't data syncing from Odoo?"
- User: "Diagnose Odoo API issues"
## Common Issues and Solutions:
### ❌ Connection Failed
**Error**: Cannot reach Odoo URL
**Solutions**:
- Verify URL is correct (include https://)
- Check internet connection
- Test URL in browser
- Check firewall/VPN settings
### ❌ Authentication Failed
**Error**: Invalid API key or credentials
**Solutions**:
- Regenerate API key in Odoo (Settings → Users → API Keys)
- Verify username matches API key owner
- Check for typos in `.env` file
- Ensure API key has not expired
### ❌ Model Not Found
**Error**: Model doesn't exist or no access
**Solutions**:
- Verify model exists in Odoo Studio
- Check model name includes `x_` prefix
- Verify user has read/write permissions
- Check model is published (not in draft mode)
### ❌ CORS Error
**Error**: Blocked by CORS policy
**Solutions**:
- Use server-side API proxy (recommended)
- Configure CORS in Odoo (not recommended)
- Check API route is working correctly
### ❌ Sync Not Working
**Error**: Records not updating
**Solutions**:
- Check browser console for errors
- Verify sync interval is running
- Clear cache and try again
- Check Odoo server is not down
### ❌ Permission Denied
**Error**: Cannot create/update records
**Solutions**:
- Verify user has write permission on model
- Check required fields are included
- Verify field types match expectations
- Check for validation rules in Odoo
## Development Tools:
Provide user with helpful commands:
```bash
# Watch network requests
# Open browser DevTools → Network tab
# View cache contents
localStorage.getItem('[model]Cache')
# Force cache clear
localStorage.clear()
# Monitor sync in console
# Look for "Syncing..." messages
```
## After Testing:
If all tests pass:
- Confirm the application is working correctly
- Suggest running tests periodically
- Recommend monitoring in production
If tests fail:
- Provide specific error messages
- Offer step-by-step troubleshooting
- Suggest checking Odoo server logs
- Offer to help fix configuration
## Advanced Diagnostics:
For complex issues:
1. Export full diagnostic report
2. Check Odoo server logs
3. Review browser console errors
4. Analyze network traffic
5. Test with different API keys
6. Try with different models
7. Compare with working examples

694
commands/troubleshoot.md Normal file
View File

@@ -0,0 +1,694 @@
Common issues and solutions for Odoo PWA projects.
## What this command does:
- Lists common problems and their solutions
- Provides step-by-step debugging guides
- Offers troubleshooting workflows
- Helps diagnose connection, sync, and build issues
- Links to relevant documentation and tools
---
## Quick Diagnostic Checklist ✅
Before diving into specific issues, run through this checklist:
```
□ .env file exists and has all required variables
□ Odoo URL is correct and reachable
□ API key is valid and not expired
□ Database name is correct
□ Model name includes x_ prefix
□ Development server is running
□ No errors in browser console
□ Internet connection is working
□ Node.js version is 18 or higher
```
**Quick Test:** Run `/test-connection` to diagnose most issues automatically.
---
## Connection Issues 🔌
### Problem: Cannot connect to Odoo
**Symptoms:**
- "Connection refused" error
- "Network error" in console
- Timeout errors
- No data loading
**Solutions:**
#### 1. Verify Odoo URL
```bash
# Test if URL is reachable
curl -I https://yourcompany.odoo.com
# Expected: HTTP 200 or 301/302
```
**Common mistakes:**
- Missing `https://`
- Extra trailing slash
- Wrong subdomain
- Typo in URL
**Fix:**
```bash
# Wrong
VITE_ODOO_URL=yourcompany.odoo.com
VITE_ODOO_URL=https://yourcompany.odoo.com/
# Right
VITE_ODOO_URL=https://yourcompany.odoo.com
```
#### 2. Check firewall / VPN
- Try accessing Odoo URL in browser
- Disable VPN temporarily
- Check corporate firewall rules
- Try from different network
#### 3. Verify environment variables loaded
```javascript
// Add to your code temporarily
console.log('Odoo URL:', import.meta.env.VITE_ODOO_URL);
console.log('Database:', import.meta.env.VITE_ODOO_DB);
```
**If undefined:**
- Restart development server
- Check variable names (case-sensitive)
- Ensure variables start with `VITE_`
---
## Authentication Issues 🔐
### Problem: Invalid API key / Authentication failed
**Symptoms:**
- "Invalid credentials" error
- "Access denied" message
- 401 Unauthorized errors
- UID is null
**Solutions:**
#### 1. Regenerate API Key
1. Log into Odoo
2. Go to Settings → Users & Companies → Users
3. Open your user record
4. Go to "API Keys" tab
5. Click "New API Key"
6. Copy the key immediately (shown only once!)
7. Update `.env` file:
```bash
ODOO_API_KEY=your_new_api_key_here
```
8. Restart development server
#### 2. Verify username matches
```bash
# Username must match the API key owner
ODOO_USERNAME=john.doe@company.com # ✅ Correct
ODOO_USERNAME=John Doe # ❌ Wrong
```
#### 3. Check user permissions
- Ensure user has access to the model
- Verify read/write permissions
- Check if user account is active
- Verify not locked out
#### 4. Test authentication manually
```javascript
// In browser console
fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'search',
model: 'res.partner',
domain: [],
fields: ['name'],
limit: 1
})
})
.then(r => r.json())
.then(console.log);
```
---
## Model Access Issues 📋
### Problem: Model not found / No records returned
**Symptoms:**
- "Model does not exist" error
- Empty array returned
- "Access rights" error
- Records don't appear
**Solutions:**
#### 1. Verify model name
```bash
# Check model name includes x_ prefix
VITE_MODEL_NAME=x_expense # ✅ Correct
VITE_MODEL_NAME=expense # ❌ Wrong
```
#### 2. Check model exists in Odoo
1. Log into Odoo
2. Go to Settings → Technical → Database Structure → Models
3. Search for your model name
4. Verify it exists and is active
#### 3. Check field names
```javascript
// Fields must use full name with x_studio_ prefix
const fields = [
'x_studio_name', // ✅ Correct
'x_studio_amount', // ✅ Correct
'name', // ❌ Wrong (unless it's a standard field)
'amount' // ❌ Wrong
];
```
#### 4. Verify permissions
- User must have read access to model
- Check access rights in Odoo Studio
- Verify record rules don't filter all records
- Test with admin user
#### 5. Check if model is published
- In Odoo Studio, verify model is not in draft mode
- Ensure model is accessible via API
- Check if model requires special access
---
## Sync Issues 🔄
### Problem: Data not syncing
**Symptoms:**
- Old data displayed
- Changes don't appear
- "Last synced" time not updating
- Background sync not working
**Solutions:**
#### 1. Check browser console
Look for:
- Network errors
- JavaScript errors
- CORS errors
- Authentication errors
#### 2. Verify sync mechanism
```javascript
// Check if sync is running
// Look for these console logs:
"Syncing x_expense..."
"Fetched X new records"
"Cache updated"
```
#### 3. Force refresh
```javascript
// In browser console
expenseCache.refresh();
```
#### 4. Clear cache and reload
```javascript
// In browser console
localStorage.clear();
// Then refresh page
```
#### 5. Check sync interval
```javascript
// Verify sync timer is running
// Default: 3 minutes (180,000ms)
// Look in cache store for:
setInterval(() => sync(), 180000);
```
#### 6. Test incremental sync
```javascript
// Check lastRecordId is updating
const cacheData = localStorage.getItem('expenseCache');
console.log(JSON.parse(cacheData));
// Should show: { lastRecordId: X, lastSyncTime: Y }
```
---
## Offline Mode Issues 📵
### Problem: Offline mode not working
**Symptoms:**
- App doesn't work without internet
- "No connection" errors when offline
- Service worker not registered
- Data not available offline
**Solutions:**
#### 1. Verify service worker registered
```javascript
// In browser console
navigator.serviceWorker.getRegistration()
.then(reg => console.log('Service Worker:', reg));
```
#### 2. Check cache stores
```javascript
// Verify data is cached
localStorage.getItem('expenseCache');
// Should return JSON string
// Check IndexedDB
// Open DevTools → Application → IndexedDB
// Look for your database and tables
```
#### 3. Test offline mode
1. Load app while online
2. Open DevTools → Network tab
3. Enable "Offline" checkbox
4. Refresh page
5. App should still work
#### 4. Build and test production
```bash
# Offline mode works better in production build
npm run build
npm run preview
```
#### 5. Check manifest.json
Verify PWA manifest is correct:
- Located in `/static/manifest.json`
- Has correct `start_url`
- Has valid icons
---
## Build / Deployment Issues 🚀
### Problem: Build fails
**Symptoms:**
- `npm run build` returns errors
- TypeScript errors
- Module not found errors
- Build process hangs
**Solutions:**
#### 1. Check Node version
```bash
node --version
# Must be v18 or higher
# If too old:
nvm install 18
nvm use 18
```
#### 2. Clean install
```bash
rm -rf node_modules package-lock.json
npm install
```
#### 3. Check for errors
```bash
# Run build with verbose output
npm run build -- --verbose
```
#### 4. Verify environment variables
```bash
# For production build, set env vars:
VITE_ODOO_URL=https://yourcompany.odoo.com \
VITE_ODOO_DB=yourcompany-main \
npm run build
```
#### 5. Check imports
- Verify all imports are correct
- Check for circular dependencies
- Ensure all files exist
---
### Problem: Deployment fails
**Symptoms:**
- Vercel/Netlify build fails
- Environment variables not working
- 404 errors in production
- Blank page after deployment
**Solutions:**
#### 1. Set environment variables
In hosting dashboard:
- Add all `VITE_*` variables
- Add `ODOO_API_KEY`
- Add `ODOO_USERNAME`
- Redeploy after adding
#### 2. Check build logs
- Review deployment logs
- Look for specific errors
- Check Node version in platform
#### 3. Test build locally
```bash
npm run build
npm run preview
# Test at http://localhost:4173
```
#### 4. Verify base path
```javascript
// For GitHub Pages or subpath deployment
// vite.config.js
export default {
base: '/your-repo-name/'
};
```
#### 5. Check API routes
- Ensure serverless functions deploy correctly
- Verify function size < 50MB
- Check function logs in platform dashboard
---
## Performance Issues ⚡
### Problem: App is slow
**Symptoms:**
- Slow initial load
- Laggy UI
- Long sync times
- High memory usage
**Solutions:**
#### 1. Optimize initial load
```javascript
// Limit initial fetch
const records = await odoo.searchRecords(
model,
[],
fields,
100 // Only fetch first 100
);
```
#### 2. Add pagination
```javascript
// Load more on scroll
let page = 1;
const pageSize = 20;
async function loadMore() {
const offset = (page - 1) * pageSize;
const more = await odoo.searchRecords(
model, [], fields, pageSize, offset
);
page++;
return more;
}
```
#### 3. Optimize bundle size
```bash
# Analyze bundle
npm run build -- --analyze
# Lazy load routes
// SvelteKit (automatic)
// React
const ExpenseList = lazy(() => import('./ExpenseList'));
// Vue
const ExpenseList = () => import('./ExpenseList.vue');
```
#### 4. Reduce sync frequency
```javascript
// Increase sync interval
const SYNC_INTERVAL = 5 * 60 * 1000; // 5 minutes instead of 3
```
#### 5. Optimize images
- Compress images before upload
- Use appropriate image formats
- Lazy load images
---
## Data Issues 📊
### Problem: Wrong data displayed
**Symptoms:**
- Incorrect values shown
- Missing fields
- Corrupted data
- Date format issues
**Solutions:**
#### 1. Clear cache
```javascript
expenseCache.clearCache();
expenseCache.refresh();
```
#### 2. Verify field mapping
```javascript
// Check if fields are correctly named
console.log(records[0]);
// Should show x_studio_* fields
```
#### 3. Check data types
```javascript
// Ensure correct types
const expense = {
x_studio_amount: 45.50, // number ✅
x_studio_date: '2025-01-15', // string (ISO) ✅
x_studio_employee: [12, false] // Many2one ✅
};
```
#### 4. Format dates correctly
```javascript
// Store as ISO string
const dateString = '2025-01-15';
// Display formatted
new Date(dateString).toLocaleDateString();
```
#### 5. Handle Many2one fields
```javascript
// Many2one can be [id, name] or just id
function getPartnerId(field) {
return Array.isArray(field) ? field[0] : field;
}
function getPartnerName(field) {
return Array.isArray(field) ? field[1] : null;
}
```
---
## CORS Issues 🚫
### Problem: CORS error
**Symptoms:**
- "Blocked by CORS policy" in console
- Requests fail in browser but work in Postman
- Preflight errors (OPTIONS)
**Solutions:**
#### 1. Use server-side proxy (recommended)
All generated PWAs include server-side API routes. Ensure you're using them:
```javascript
// ✅ Good: Goes through server proxy
fetch('/api/odoo', { ... });
// ❌ Bad: Direct call to Odoo (CORS error)
fetch('https://yourcompany.odoo.com/jsonrpc', { ... });
```
#### 2. Verify API route works
```javascript
// Test in browser console
fetch('/api/odoo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'search',
model: 'res.partner',
domain: [],
fields: ['name'],
limit: 1
})
})
.then(r => r.json())
.then(console.log);
```
#### 3. Check if deployed correctly
- Verify serverless functions deployed
- Check function logs
- Ensure environment variables set
---
## Browser-Specific Issues 🌐
### Problem: Works in Chrome but not Safari/Firefox
**Symptoms:**
- Different behavior across browsers
- Safari-specific errors
- Mobile browser issues
**Solutions:**
#### 1. Check browser compatibility
- Test in multiple browsers
- Check for console errors in each
- Verify IndexedDB support
#### 2. Safari-specific
- Safari has stricter storage limits
- Check if localStorage/IndexedDB working
- Test in private mode
#### 3. Mobile browsers
- Test on actual devices
- Check responsive design
- Verify touch interactions work
---
## Debugging Tools & Commands 🔧
### Essential Commands
```bash
# Test connection
/test-connection
# View full help
/help
# See architecture details
/architecture
# Clear cache and start fresh
/clear-cache
# Fix sync issues
/fix-sync
```
### Browser DevTools
```javascript
// Network tab
// - See all API calls
// - Check request/response
// - View timing
// Console tab
// - See error messages
// - Run test commands
// - Inspect data
// Application tab
// - View localStorage
// - Inspect IndexedDB
// - Check Service Workers
// - View Cache Storage
// Performance tab
// - Profile slow operations
// - Find bottlenecks
```
### Useful Console Commands
```javascript
// View cache
localStorage.getItem('expenseCache');
// Clear cache
localStorage.clear();
// Force refresh
expenseCache.refresh();
// View current records
console.log($expenseCache); // SvelteKit
// Test API
fetch('/api/odoo', { /* ... */ })
.then(r => r.json())
.then(console.log);
```
---
## Getting Help 💬
### Before asking for help:
1. Run `/test-connection`
2. Check browser console for errors
3. Review this troubleshooting guide
4. Try solutions listed above
5. Test with minimal example
### When reporting issues:
Include:
- Exact error message
- Browser and version
- Node.js version
- Steps to reproduce
- What you've already tried
- Relevant code snippets
### Helpful resources:
- `/help` - Plugin documentation
- `/examples` - Usage examples
- `/architecture` - Design patterns
- `/api-reference` - API documentation
- Odoo docs: https://www.odoo.com/documentation/
- Framework docs (SvelteKit/React/Vue)
---
## Example prompts to use this command:
- `/troubleshoot` - Show troubleshooting guide
- User: "Why isn't my data syncing?"
- User: "I'm getting a connection error"
- User: "Help! Nothing works!"
## Still Stuck?
If these solutions don't help:
1. Run `/test-connection` for detailed diagnostics
2. Check generated project's CLAUDE.md
3. Review Odoo server logs
4. Test with different Odoo model
5. Try generating fresh project to compare
Most issues are related to configuration or permissions. Double-check your `.env` file and Odoo settings!

505
commands/update-deps.md Normal file
View File

@@ -0,0 +1,505 @@
Update dependencies in your Odoo PWA project to latest compatible versions.
## What this command does:
- Checks for outdated dependencies
- Updates packages to latest versions
- Tests the application after updates
- Fixes breaking changes if needed
- Updates lock files
- Verifies everything still works
## Prerequisites:
- Current directory is an Odoo PWA project
- Git repository (recommended for easy rollback)
- Latest npm installed
---
## Update Strategy
### Safe Update (Recommended)
Updates to latest compatible versions within semver ranges.
```bash
npm update
```
### Major Update (Requires testing)
Updates to latest versions including major releases.
```bash
npm outdated # See what's outdated
npm update # Update minor/patch
npx npm-check-updates -u # Update majors
npm install
```
---
## Steps:
### 1. Check Current Status
```bash
# See current versions
npm list --depth=0
# See outdated packages
npm outdated
```
### 2. Create Backup
```bash
# Commit current state
git add .
git commit -m "Pre-dependency update checkpoint"
# Or backup package files
cp package.json package.json.backup
cp package-lock.json package-lock.json.backup
```
### 3. Update Dependencies
#### Minor/Patch Updates (Safe)
```bash
npm update
npm install
```
#### Major Updates (Test carefully)
```bash
# Install npm-check-updates if needed
npm install -g npm-check-updates
# Preview updates
ncu
# Update package.json
ncu -u
# Install new versions
npm install
```
### 4. Framework-Specific Updates
#### SvelteKit
```bash
# Update Svelte + SvelteKit
npm update @sveltejs/kit @sveltejs/adapter-static
npm update svelte
# Check for breaking changes
# https://github.com/sveltejs/kit/blob/master/CHANGELOG.md
```
#### React
```bash
# Update React
npm update react react-dom
# Update related packages
npm update @types/react @types/react-dom
```
#### Vue
```bash
# Update Vue
npm update vue
# Update related packages
npm update @vitejs/plugin-vue
```
### 5. Update Build Tools
```bash
# Update Vite
npm update vite
# Update PWA plugin
npm update vite-plugin-pwa @vite-pwa/sveltekit
```
### 6. Test Everything
#### Run Development Server
```bash
npm run dev
```
Check:
- ✅ Server starts without errors
- ✅ App loads correctly
- ✅ No console errors
- ✅ All routes work
#### Test Core Functionality
- ✅ Odoo connection works
- ✅ Data loads from cache
- ✅ Sync works
- ✅ CRUD operations work
- ✅ Offline mode works
#### Build for Production
```bash
npm run build
```
Check:
- ✅ Build completes without errors
- ✅ No warnings about deprecations
- ✅ Bundle size is reasonable
#### Preview Production Build
```bash
npm run preview
```
Test the same functionality in production mode.
### 7. Run Connection Test
```bash
# If /test-connection command is available
/test-connection
```
### 8. Commit Changes
```bash
git add package.json package-lock.json
git commit -m "Update dependencies to latest versions"
```
---
## Common Issues & Solutions
### Issue: Build fails after update
**Solution:**
```bash
# Revert updates
git checkout package.json package-lock.json
npm install
# Try updating one package at a time
npm update vite
npm run build # Test
npm update @sveltejs/kit
npm run build # Test
# Continue one by one
```
### Issue: TypeScript errors
**Solution:**
```bash
# Update TypeScript
npm update typescript
# Update type definitions
npm update @types/node
# Regenerate tsconfig
npx tsc --init
```
### Issue: Import errors
**Solution:**
```javascript
// Old import might be:
import { foo } from 'package';
// New import might be:
import { foo } from 'package/foo';
// Check package's CHANGELOG for migration guide
```
### Issue: Service Worker errors
**Solution:**
```bash
# Update PWA plugin
npm update vite-plugin-pwa
# Check configuration
# vite.config.js
VitePWA({
// Update config as needed
})
```
### Issue: Peer dependency warnings
**Solution:**
```bash
# Install peer dependencies
npm install <missing-peer-dep>
# Or use --force (not recommended)
npm install --force
```
---
## Breaking Changes to Watch For
### Vite 5+
- May require Node 18+
- ESM-only packages
- Updated config format
### SvelteKit 2+
- Svelte 5 syntax (runes)
- Updated adapter config
- New routing conventions
### React 19+
- New JSX transform
- Updated hooks behavior
- Server components
### Vue 3.4+
- New compiler optimizations
- Updated Composition API
- Better TypeScript support
---
## Update Checklist
After updating, verify:
```
□ npm run dev works
□ npm run build succeeds
□ npm run preview works
□ No console errors
□ Odoo connection works
□ Data syncs correctly
□ CRUD operations work
□ Offline mode works
□ Service worker registered
□ Tests pass (if any)
□ No TypeScript errors
□ No ESLint warnings
□ Documentation updated
```
---
## Selective Updates
### Update Only Production Dependencies
```bash
npm update --prod
```
### Update Specific Package
```bash
npm update vite
npm update @sveltejs/kit
```
### Update to Specific Version
```bash
npm install vite@5.0.0
npm install svelte@5.0.0
```
### Keep Package at Current Version
```json
// package.json
{
"dependencies": {
"some-package": "1.2.3" // No ^ or ~ = exact version
}
}
```
---
## Best Practices
### 1. Update Regularly
- Check weekly for security updates
- Update monthly for feature updates
- Test before deploying
### 2. Read Changelogs
- Check CHANGELOG.md for breaking changes
- Review migration guides
- Test thoroughly
### 3. Update One Category at a Time
```bash
# 1. Framework
npm update svelte @sveltejs/kit
# 2. Build tools
npm update vite
# 3. Dependencies
npm update # All others
```
### 4. Keep Lock Files
- Commit `package-lock.json`
- Ensure consistent installs
- Track exact versions
### 5. Test in Staging
- Deploy to staging first
- Test all functionality
- Then deploy to production
---
## Security Updates
### Check for Vulnerabilities
```bash
npm audit
```
### Fix Automatically
```bash
npm audit fix
```
### Fix with Breaking Changes
```bash
npm audit fix --force
```
### Review Details
```bash
npm audit --json
```
---
## Automated Updates (Optional)
### Using Dependabot (GitHub)
Create `.github/dependabot.yml`:
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
```
### Using Renovate
Create `renovate.json`:
```json
{
"extends": ["config:base"],
"schedule": ["before 10am on monday"]
}
```
---
## Rollback Plan
### If Something Breaks
#### Quick Rollback
```bash
git checkout package.json package-lock.json
npm install
```
#### Restore from Backup
```bash
cp package.json.backup package.json
cp package-lock.json.backup package-lock.json
npm install
```
#### Git Reset
```bash
git reset --hard HEAD~1
npm install
```
---
## After Update
### Update Documentation
- Note any breaking changes
- Update README if needed
- Document new features used
### Notify Team
- Share what was updated
- Note any changes in behavior
- Update staging/production
### Monitor Production
- Watch error logs
- Check performance metrics
- Monitor user reports
---
## Example prompts to use this command:
- `/update-deps` - Update all dependencies
- User: "Update my dependencies"
- User: "Check for package updates"
- User: "My packages are outdated"
## Related Commands:
- `/fix-sync` - If sync breaks after update
- `/test-connection` - Verify Odoo still works
- `/troubleshoot` - Fix issues after update
- `/optimize` - Check for optimizations after update
---
## Quick Update Script
Save as `update.sh`:
```bash
#!/bin/bash
echo "Backing up..."
cp package.json package.json.backup
cp package-lock.json package-lock.json.backup
echo "Checking for updates..."
npm outdated
echo "Updating..."
npm update
echo "Installing..."
npm install
echo "Testing..."
npm run build
if [ $? -eq 0 ]; then
echo "✅ Build successful!"
echo "Run: npm run dev to test"
else
echo "❌ Build failed! Rolling back..."
cp package.json.backup package.json
cp package-lock.json.backup package-lock.json
npm install
fi
```
Usage:
```bash
chmod +x update.sh
./update.sh
```