con un clic
data-analyst
Analyse data in the demo SQLite database using SQL queries
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Analyse data in the demo SQLite database using SQL queries
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
You are a QC inspector agent for a rubber duck factory. You look at batch photos, run quality control inspections, and manage dispositions.
You are an mcp expert, from prompting to mcp tool definition, documentation and debugging.
Connect to and interact with the MyForterro API (authentication, tenant management, AI agents, invoicing, inference).
You are a UX expert, that values consistency above all
Run, maintain, and extend the duck-demo API contract test suite (REST + MCP tools).
Basado en la clasificación ocupacional SOC
| name | data-analyst |
| description | Analyse data in the demo SQLite database using SQL queries |
| user-invokable | true |
Answer data questions about the duck-demo ERP by running SQL against the SQLite database at demo.db in the project root.
Use this skill when the user asks about data stored in the database: record counts, status distributions, timing analysis, trends, throughput, lead times, etc.
source venv/bin/activatesqlite3 demo.db "SELECT ..."
sqlite3 demo.db <<'SQL' ... SQL or pipe a file.-header -column for readable output, or -json when you need to post-process.ea as-is. The uom column on the items table tells you which unit applies.YYYY-MM-DD. Omit the time portion unless it matters for the question.LIMIT 20 unless the user asks for everything. Mention when results are truncated.Read schema.sql in the project root for the full DDL. Key points below.
All TEXT timestamp columns store ISO-8601 strings (YYYY-MM-DD HH:MM:SS).
The system runs on simulated time stored in simulation_state.sim_time. Use it as "now":
SELECT sim_time FROM simulation_state WHERE id = 1;
| Entity | Table | Statuses (in order) |
|---|---|---|
| Quote | quotes | draft → sent → accepted / rejected / expired / superseded |
| Sales Order | sales_orders | draft → confirmed → completed |
| Production Order | production_orders | planned → waiting → ready → in_progress → completed |
| Production Operation | production_operations | pending → in_progress → completed |
| Shipment | shipments | planned → dispatched → delivered |
| Purchase Order | purchase_orders | ordered → received |
| Invoice | invoices | draft → issued → paid / overdue |
emails | draft → sent |
customer ──< quotes ──< quote_lines
│
▼ (accept_quote creates SO)
customer ──< sales_orders ──< sales_order_lines
│
├──< production_orders ──< production_operations
│
├──< sales_order_shipments >── shipments ──< shipment_lines
│
├──< invoices ──< payments
│
└──< emails
sales_orders.quote_id → quotes.idproduction_orders.sales_order_id → sales_orders.idproduction_orders.recipe_id → recipes.idrecipe_ingredients.recipe_id → recipes.idrecipe_operations.recipe_id → recipes.idproduction_operations.production_order_id → production_orders.idproduction_operations.recipe_operation_id → recipe_operations.idinvoices.sales_order_id → sales_orders.idpayments.invoice_id → invoices.iditems.default_supplier_id → suppliers.idpurchase_orders.item_id → items.idAll qty / on_hand columns are INTEGER in the smallest base unit:
ea → pieces (use as-is)g → grams (divide by 1000 for kg in display)ml → millilitres (divide by 1000 for L in display)Check items.uom to know which unit applies.
| Question | Columns to use |
|---|---|
| Quote creation → acceptance delay | quotes.created_at vs quotes.accepted_at |
| Quote creation → SO creation | quotes.created_at vs sales_orders.created_at |
| SO confirmed → production start | sales_orders.created_at vs production_orders.started_at |
| Production duration | production_orders.started_at vs production_orders.completed_at |
| Operation duration | production_operations.started_at vs production_operations.completed_at |
| Shipment transit time | shipments.dispatched_at vs shipments.delivered_at |
| Order-to-delivery | sales_orders.created_at vs shipments.delivered_at (join via sales_order_shipments) |
| Invoice payment delay | invoices.issued_at vs invoices.paid_at |
Time differences (SQLite lacks DATEDIFF; use julianday):
SELECT ROUND(julianday(accepted_at) - julianday(created_at), 2) AS days_to_accept
FROM quotes
WHERE accepted_at IS NOT NULL;
Status distribution:
SELECT status, COUNT(*) AS n FROM quotes GROUP BY status ORDER BY n DESC;
Join SO → production → operations for end-to-end timing:
SELECT so.id AS so_id,
so.created_at AS so_created,
po.started_at AS prod_start,
po.completed_at AS prod_done,
ROUND(julianday(po.completed_at) - julianday(so.created_at), 1) AS days_total
FROM sales_orders so
JOIN production_orders po ON po.sales_order_id = so.id
WHERE po.completed_at IS NOT NULL
LIMIT 20;
If the meaning of a column or status transition is not obvious from the schema, look into the corresponding service file in services/ (e.g. services/quote.py, services/production.py). The scenario scripts in scenarios/ also show the intended data-generation flow. Only do this when the schema alone doesn't answer the question.