supabase
Handles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
Validate code follows frappe-microservice-lib patterns, security best practices, and framework conventions.
Full skill instructions
Check if code follows frappe-microservice-lib patterns and best practices.
1. Authentication
# ✅ Good
@app.secure_route('/endpoint', methods=['GET'])
def handler(user):
pass
# ❌ Bad - no authentication
@app.route('/endpoint', methods=['GET'])
def handler():
pass
2. Tenant Isolation
# ✅ Good
tenant_id = get_current_tenant_id()
app.set_tenant_id(tenant_id)
data = app.tenant_db.get_all('DocType')
# ❌ Bad - no tenant isolation
data = frappe.db.get_all('DocType')
3. SQL Injection Prevention
# ✅ Good - parameterized
result = app.tenant_db.sql(
"SELECT * FROM `tabDocType` WHERE tenant_id = %s AND status = %s",
(tenant_id, 'Draft'),
as_dict=True
)
# ❌ Bad - string formatting
result = app.tenant_db.sql(
f"SELECT * FROM `tabDocType` WHERE tenant_id = '{tenant_id}'"
)
1. Tenant Resolution Function
# ✅ Good - proper tenant resolution
def get_current_tenant_id():
from flask import g
from frappe_microservice import get_user_tenant_id
if hasattr(g, 'tenant_id') and g.tenant_id:
return g.tenant_id
if hasattr(g, 'current_user') and g.current_user:
user_email = g.current_user
if user_email in ('Guest', 'Administrator'):
return None
tenant_id = get_user_tenant_id(user_email)
if tenant_id:
g.tenant_id = tenant_id
return tenant_id
return None
# ❌ Bad - missing security checks
def get_current_tenant_id():
return frappe.session.user
2. Database Access
# ✅ Good - uses tenant_db
app.set_tenant_id(tenant_id)
doc = app.tenant_db.get_doc('DocType', name)
# ❌ Bad - uses frappe.db directly
doc = frappe.get_doc('DocType', name)
3. Transaction Management
# ✅ Good - proper transaction handling
try:
frappe.db.begin()
doc1 = app.tenant_db.insert_doc('DocType1', data1)
doc2 = app.tenant_db.insert_doc('DocType2', data2)
app.tenant_db.commit()
except Exception as e:
app.tenant_db.rollback()
raise
# ❌ Bad - no transaction management
doc1 = app.tenant_db.insert_doc('DocType1', data1)
doc2 = app.tenant_db.insert_doc('DocType2', data2)
1. Service Initialization
# ✅ Good - proper initialization
app = create_microservice(
"service-name",
get_tenant_id_func=get_current_tenant_id,
load_framework_hooks=['frappe', 'erpnext']
)
# ❌ Bad - missing tenant function
app = create_microservice("service-name")
2. Error Handling
# ✅ Good - proper error responses
try:
doc = app.tenant_db.get_doc('DocType', name)
return {"data": doc.as_dict()}
except frappe.DoesNotExistError:
return {"error": "Document not found"}, 404
except Exception as e:
return {"error": str(e)}, 500
# ❌ Bad - no error handling
doc = app.tenant_db.get_doc('DocType', name)
return {"data": doc.as_dict()}
3. Input Validation
# ✅ Good - validates input
data = request.json
if not data:
return {"error": "No data provided"}, 400
if not data.get('required_field'):
return {"error": "required_field is required"}, 400
# ❌ Bad - no validation
data = request.json
doc = app.tenant_db.insert_doc('DocType', data)
1. Controller Structure
# ✅ Good - proper controller
from frappe_microservice.controller import DocumentController
class SalesOrder(DocumentController):
def validate(self):
if not self.customer:
self.throw("Customer is required")
def before_insert(self):
if not self.status:
self.status = 'Draft'
# ❌ Bad - not using DocumentController
class SalesOrder:
def validate(self):
pass
2. Controller Registration
# ✅ Good - registers controllers
from frappe_microservice.controller import setup_controllers
setup_controllers(app, "./controllers")
# ❌ Bad - controllers not registered
# Controllers won't be called
1. Hook Registration
# ✅ Good - proper hook registration
@app.tenant_db.on('Sales Order', 'before_insert')
def set_defaults(doc):
if not doc.status:
doc.status = 'Draft'
# ❌ Bad - hook not registered with app
def set_defaults(doc):
pass
2. Hook Error Handling
# ✅ Good - handles errors
@app.tenant_db.on('Sales Order', 'validate')
def validate_order(doc):
try:
if not doc.customer:
frappe.throw("Customer is required")
except frappe.ValidationError:
raise
except Exception as e:
frappe.log_error(f"Error: {e}")
# ❌ Bad - no error handling
@app.tenant_db.on('Sales Order', 'validate')
def validate_order(doc):
if not doc.customer:
raise Exception("Customer is required")
1. Missing tenant_id Setting
# ❌ Bad - forgot to set tenant_id
@app.secure_route('/endpoint', methods=['GET'])
def handler(user):
data = app.tenant_db.get_all('DocType') # Will fail!
# ✅ Good
@app.secure_route('/endpoint', methods=['GET'])
def handler(user):
tenant_id = get_current_tenant_id()
app.set_tenant_id(tenant_id)
data = app.tenant_db.get_all('DocType')
2. Using frappe.session Directly
# ❌ Bad - direct session access
user = frappe.session.user
# ✅ Good - use injected user
@app.secure_route('/endpoint', methods=['GET'])
def handler(user): # user is injected
pass
3. Missing Commit
# ❌ Bad - no commit
doc = app.tenant_db.insert_doc('DocType', data)
return {"success": True}
# ✅ Good - commits transaction
doc = app.tenant_db.insert_doc('DocType', data)
app.tenant_db.commit()
return {"success": True}
@app.secure_routeapp.tenant_db (not frappe.db)DocumentController@app.tenant_db.on()frappe.session access in endpoints@app.secure_routeapp.tenant_dbHandles the full Supabase workflow from schema changes to deployment, with built-in security guardrails that catch common traps like RLS...
Comprehensive guides and best practices for Neon Serverless Postgres, covering setup, connection methods, authentication, and platform APIs.
Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.
A skill to evaluate how secure Firestore security rules are. Use this when Firestore security rules are updated to ensure that the generated rules are extremely secure and robust.
Official skill for integrating Firebase AI Logic (Gemini API) into web applications. Covers setup, multimodal inference, structured output, and security.
Complete Better Auth server and client setup with database adapters, session management, plugins, and security configuration.
Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
Complete Cloudflare platform integration with decision trees for compute, storage, AI, networking, security, and infrastructure-as-code.
Run Azure compliance and security audits with azqr plus Key Vault expiration checks. Covers best-practice assessment, resource review, policy/compliance validation, and security posture checks. WHEN: compliance scan, security audit, BEFORE running azqr (compliance cli tool), Azure best practices, Key Vault expiration check, expired certificates, expiring secrets, orphaned resources, compliance assessment.
Send, read, and manage Gmail messages, drafts, labels, and account settings.
Comprehensive website auditing across 230+ rules in 21 categories including SEO, performance, security, and accessibility.
Shared authentication, CLI syntax, and output formatting patterns for gws Google Workspace commands.
Discover your celebrity doppelgänger with StarByFace!
GeoSpy: Pricing, Features, FAQs, and Alternatives for AI Teams
Detect AI-generated voices to protect against audio fraud.
Ensure Your Content's Originality with AI Plagiarism Checker
Upscale images by 400% without quality loss
Protect your social media from copyright disputes
Accurately Detect AI-Generated Content with TheChecker.AI
Chrome extension that detects and flags AI-generated content