PageSourceSearch

https://groundedos.ai/assets/DeveloperMode-BMVEdhoV.js

js groundedos.ai collected 2026-10-05 12:57:53 UTC 18,188 bytes, 55 lines download raw bytes

1import{n as M,k as $,aC as Q,J as j,K as l,r as v,j as e,C as _,b,c as w,i as C,at as U,aM as Y,B as m,aG as X,au as V,av as W,aw as Z,aD as J,aE as y,bG as ee,bj as se,bH as ae,aF as R,q as g,bb as te,e as k,y as d,ax as re,bC as ie,ac as ne,Q as S,R as L,V as p,h as ce,bI as oe,W as N,Z as le}from"./index-_XRcRoWC.js";import{P as de}from"./PageHeader-GFqnGblc.js";import{S as me}from"./switch-yRmop0O4.js";import{T as xe,a as he,b as O,c as x,d as pe,e as h}from"./table-C34BedAi.js";import{A as ue,a as je,b as ye,c as ge,d as fe,e as ve,f as Ne,g as _e,h as be}from"./alert-dialog-tB-ZoN2s.js";import{u as we}from"./useQuery-CsY5Jov_.js";import{u as D}from"./useMutation-ClQQAB4a.js";import{K as F}from"./key-BjKJGqUA.js";import{T as Ce}from"./trash-2-Cfryp4g4.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const ke=M("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]),q={"read:forecasts":"Read Forecasts","read:inventory":"Read Inventory","read:labor":"Read Labor Data","read:sales":"Read Sales Data","read:employees":"Read Employees","write:inventory":"Write Inventory","write:purchase_orders":"Create Purchase Orders","read:analytics":"Read Analytics","admin:full":"Full Admin Access"};function Ae(){const{currentTenant:a}=$(),c=Q(),{data:o,isLoading:A}=we({queryKey:["api-keys",a==null?void 0:a.id],queryFn:async()=>{var i;if(!(a!=null&&a.id))return[];await j.functions.invoke("api-keys",{method:"GET",headers:{"Content-Type":"application/json"},body:null});const t=await fetch(`https://rvavlzhxwlsubexecpbp.supabase.co/functions/v1/api-keys?tenant_id=${a.id}`,{headers:{Authorization:`Bearer ${(i=(await j.auth.getSession()).data.session)==null?void 0:i.access_token}`,"Content-Type":"application/json"}});if(!t.ok)throw new Error("Failed to fetch API keys");return t.json()},enabled:!!(a!=null&&a.id)}),E=D({mutationFn:async t=>{if(!(a!=null&&a.id))throw new Error("No tenant selected");const{data:i,error:n}=await j.functions.invoke("api-keys",{body:{...t,tenant_id:a.id}});if(n)throw n;return i},onSuccess:()=>{c.invalidateQueries({queryKey:["api-keys"]}),l.success("API key created successfully")},onError:t=>{l.error(`Failed to create API key: ${t.message}`)}}),I=D({mutationFn:async t=>{var n;if(!(a!=null&&a.id))throw new Error("No tenant selected");const i=await fetch(`https://rvavlzhxwlsubexecpbp.supabase.co/functions/v1/api-keys?id=${t}&tenant_id=${a.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${(n=(await j.auth.getSession()).data.session)==null?void 0:n.access_token}`,"Content-Type":"application/json"}});if(!i.ok)throw new Error("Failed to delete API key");return i.json()},onSuccess:()=>{c.invalidateQueries({queryKey:["api-keys"]}),l.success("API key deleted")},onError:t=>{l.error(`Failed to delete API key: ${t.message}`)}}),f=D({mutationFn:async({id:t,is_active:i})=>{if(!(a!=null&&a.id))throw new Error("No tenant selected");const{data:n,error:u}=await j.functions.invoke("api-keys",{method:"PATCH",body:{id:t,is_active:i,tenant_id:a.id}});if(u)throw u;return n},onSuccess:()=>{c.invalidateQueries({queryKey:["api-keys"]}),l.success("API key updated")},onError:t=>{l.error(`Failed to update API key: ${t.message}`)}});return{apiKeys:o||[],isLoading:A,createKey:E,deleteKey:I,toggleKey:f}}const Ee=["read:forecasts","read:inventory","read:labor","read:sales","read:employees","write:inventory","write:purchase_orders","read:analytics","admin:full"];function Ie(){const{apiKeys:a,isLoading:c,createKey:o,deleteKey:A,toggleKey:E}=Ae(),[I,f]=v.useState(!1),[t,i]=v.useState({name:"",scopes:[],rate_limit_per_minute:60,rate_limit_per_day:1e4}),[n,u]=v.useState(null),[P,T]=v.useState(!1),G=async()=>{if(!t.name||t.scopes.length===0){l.error("Please provide a name and select at least one scope");return}const s=await o.mutateAsync(t);s.key&&u(s.key)},z=()=>{n&&(navigator.clipboard.writeText(n),l.success("API key copied to clipboard"))},K=()=>{f(!1),u(null),T(!1),i({name:"",scopes:[],rate_limit_per_minute:60,rate_limit_per_day:1e4})},B=s=>
6{i(r=>({...r,scopes:r.scopes.includes(s)?r.scopes.filter(H=>H!==s):[...r.scopes,s]}))};return e.jsxs(_,{children:[e.jsx(b,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs(w,{className:"flex items-center gap-2",children:[e.jsx(F,{className:"h-5 w-5"}),"API Keys"]}),e.jsx(C,{children:"Manage API keys for programmatic access to your organization's data"})]}),e.jsxs(U,{open:I,onOpenChange:f,children:[e.jsx(Y,{asChild:!0,children:e.jsxs(m,{children:[e.jsx(X,{className:"h-4 w-4 mr-2"}),"Create API Key"]})}),e.jsxs(V,{className:"max-w-lg",children:[e.jsxs(W,{children:[e.jsx(Z,{children:"Create New API Key"}),e.jsx(J,{children:"Create a new API key with specific permissions and rate limits"})]}),n?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border border-yellow-500/50 bg-yellow-500/10 p-4",children:[e.jsx("p",{className:"text-sm font-medium text-yellow-600 mb-2",children:"Save this key now! It won't be shown again."}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{type:P?"text":"password",value:n,readOnly:!0,className:"font-mono text-sm"}),e.jsx(m,{variant:"outline",size:"icon",onClick:()=>T(!P),children:P?e.jsx(ee,{className:"h-4 w-4"}):e.jsx(se,{className:"h-4 w-4"})}),e.jsx(m,{variant:"outline",size:"icon",onClick:z,children:e.jsx(ae,{className:"h-4 w-4"})})]})]}),e.jsx(R,{children:e.jsx(m,{onClick:K,children:"Done"})})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(g,{children:"Key Name"}),e.jsx(y,{placeholder:"e.g., Production API Key",value:t.name,onChange:s=>i(r=>({...r,name:s.target.value}))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(g,{children:"Scopes"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:Ee.map(s=>e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsx(te,{id:s,checked:t.scopes.includes(s),onCheckedChange:()=>B(s)}),e.jsx("label",{htmlFor:s,className:"text-sm cursor-pointer",children:q[s]})]},s))})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(g,{children:"Rate Limit (per minute)"}),e.jsx(y,{type:"number",value:t.rate_limit_per_minute,onChange:s=>i(r=>({...r,rate_limit_per_minute:parseInt(s.target.value)||60}))})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(g,{children:"Rate Limit (per day)"}),e.jsx(y,{type:"number",value:t.rate_limit_per_day,onChange:s=>i(r=>({...r,rate_limit_per_day:parseInt(s.target.value)||1e4}))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(g,{children:"Expiration Date (optional)"}),e.jsx(y,{type:"date",value:t.expires_at||"",onChange:s=>i(r=>({...r,expires_at:s.target.value||void 0}))})]}),e.jsxs(R,{children:[e.jsx(m,{variant:"outline",onClick:K,children:"Cancel"}),e.jsx(m,{onClick:G,disabled:o.isPending,children:o.isPending?"Creating...":"Create Key"})]})]})]})]})]})}),e.jsx(k,{children:c?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Loading..."}):a.length===0?e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No API keys created yet. Create your first key to get started."}):e.jsxs(xe,{children:[e.jsx(he,{children:e.jsxs(O,{children:[e.jsx(x,{children:"Name"}),e.jsx(x,{children:"Key Prefix"}),e.jsx(x,{children:"Scopes"}),e.jsx(x,{children:"Rate Limits"}),e.jsx(x,{children:"Last Used"}),e.jsx(x,{children:"Status"}),e.jsx(x,{className:"text-right",children:"Actions"})]})}),e.jsx(pe,{children:a.map(s=>e.jsxs(O,{children:[e.jsx(h,{className:"font-medium",children:s.name}),e.jsx(h,{children:e.jsxs("code",{className:"text-xs bg-muted px-2 py-1 rounded",children:[s.key_prefix,"..."]})}),e.jsx(h,{children:e.jsxs("div",{className:"flex flex-wrap gap-1",children:[s.scopes.slice(0,2).map(r=>e.jsx(d,{variant:"secondary",className:"text-xs",children:q[r]},r)),s.scopes.length>2&&e.jsxs(d,{variant:"outline",className:"text-xs",children:["+",s.scopes.length-2]})]})}),e.jsxs(h,{className:"text-sm text-muted-foreground",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(re,{className:"h-3 w-3"}),s.rate_limit_per_minute,"/min"]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(ie,{className:"h-3 w-3"}
6),s.rate_limit_per_day.toLocaleString(),"/day"]})]}),e.jsx(h,{className:"text-sm text-muted-foreground",children:s.last_used_at?ne(new Date(s.last_used_at),"MMM d, yyyy HH:mm"):"Never"}),e.jsx(h,{children:e.jsx(me,{checked:s.is_active,onCheckedChange:r=>E.mutate({id:s.id,is_active:r})})}),e.jsx(h,{className:"text-right",children:e.jsxs(ue,{children:[e.jsx(je,{asChild:!0,children:e.jsx(m,{variant:"ghost",size:"icon",className:"text-destructive",children:e.jsx(Ce,{className:"h-4 w-4"})})}),e.jsxs(ye,{children:[e.jsxs(ge,{children:[e.jsx(fe,{children:"Delete API Key"}),e.jsxs(ve,{children:['Are you sure you want to delete "',s.name,'"? This action cannot be undone and will immediately revoke access for any systems using this key.']})]}),e.jsxs(Ne,{children:[e.jsx(_e,{children:"Cancel"}),e.jsx(be,{onClick:()=>A.mutate(s.id),className:"bg-destructive text-destructive-foreground",children:"Delete"})]})]})]})})]},s.id))})]})})]})}const Pe=[{method:"GET",path:"/forecast/{store_id}/week",description:"Get weekly sales and traffic forecast",scopes:["read:forecasts"],response:"{ hourly_predictions, weather_impact, confidence_score }"},{method:"GET",path:"/inventory/{store_id}",description:"Get current inventory levels and projections",scopes:["read:inventory"],response:"{ ingredients[], depletion_forecast, reorder_suggestions }"},{method:"POST",path:"/inventory/{store_id}/update",description:"Update inventory quantities",scopes:["write:inventory"],response:"{ success, updated_items[] }"},{method:"GET",path:"/labor/{store_id}/heatmap",description:"Get staffing recommendations heatmap",scopes:["read:labor"],response:"{ hourly_recommendations[], staffing_status }"},{method:"GET",path:"/sales/{store_id}/daily",description:"Get daily sales summary",scopes:["read:sales"],response:"{ total_sales, transactions, avg_ticket, items_sold[] }"},{method:"GET",path:"/employees/{store_id}",description:"List employees and availability",scopes:["read:employees"],response:"{ employees[], schedules[] }"},{method:"POST",path:"/purchase-orders/create",description:"Create a new purchase order",scopes:["write:purchase_orders"],response:"{ id, status, supplier, items[] }"},{method:"GET",path:"/analytics/{store_id}/summary",description:"Get analytics dashboard data",scopes:["read:analytics"],response:"{ revenue_trend, top_items, customer_insights }"}],De={curl:`curl -X GET "https://api.groundedai.com/v1/forecast/STORE_ID/week" \\
7  -H "Authorization: Bearer YOUR_API_KEY" \\
8  -H "Content-Type: application/json"`,javascript:`const response = await fetch(
9  'https://api.groundedai.com/v1/forecast/STORE_ID/week',
10  {
11    headers: {
12      'Authorization': 'Bearer YOUR_API_KEY',
13      'Content-Type': 'application/json',
14    },
15  }
16);
17const data = await response.json();`,python:`import requests
18
19response = requests.get(
20    'https://api.groundedai.com/v1/forecast/STORE_ID/week',
21    headers={
22        'Authorization': 'Bearer YOUR_API_KEY',
23        'Content-Type': 'application/json',
24    }
25)
26data = response.json()`};function ze(){return e.jsx(e.Fragment,{children:e.jsxs("div",{className:"space-y-6",children:[e.jsx(de,{title:"Developer Mode",description:"API keys, documentation, and integration tools"}),e.jsxs(S,{defaultValue:"keys",className:"space-y-6",children:[e.jsxs(L,{children:[e.jsxs(p,{value:"keys",className:"gap-2",children:[e.jsx(F,{className:"h-4 w-4"}),"API Keys"]}),e.jsxs(p,{value:"docs",className:"gap-2",children:[e.jsx(ce,{className:"h-4 w-4"}),"Documentation"]}),e.jsxs(p,{value:"examples",className:"gap-2",children:[e.jsx(oe,{className:"h-4 w-4"}),"Code Examples"]})]}),e.jsx(N,{value:"keys",className:"space-y-6",children:e.jsx(Ie,{})}),e.jsx(N,{value:"docs",className:"space-y-6",children:e.jsxs(_,{children:[e.jsxs(b,{children:[e.jsxs(w,{className:"flex items-center gap-2",children:[e.jsx(ke,{className:"h-5 w-5"}),"API Reference"]}),e.jsx(C,{children:"Complete list of available API endpoints and their required scopes"})]}),e.jsxs(k,{children:[e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-4",children:[e.jsx("h4",{className:"font-medium mb-2",children:"Base URL"}),e.jsx("code",{className:"text-sm bg-background px-3 py-1.5 rounded border",children:"https://api.groundedai.com/v1"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-4",children:[e.jsx("h4",{className:"font-medium mb-2",children:"Authentication"}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:"Include your API key in the Authorization header:"}),e.jsx("code",{className:"text-sm bg-background px-3 py-1.5 rounded border block",children:"Authorization: Bearer gai_xxxxxxxxxxxxxxxxxxxxx"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/50 p-4",children:[e.jsx("h4",{className:"font-medium mb-2",children:"Rate Limiting"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Rate limits are configured per API key. Response headers include:"}),e.jsxs("ul",{className:"text-sm text-muted-foreground mt-2 space-y-1",children:[e.jsxs("li",{children:[e.jsx("code",{children:"X-RateLimit-Remaining-Minute"})," - Remaining requests this minute"]}),e.jsxs("li",{children:[e.jsx("code",{children:"X-RateLimit-Remaining-
26Day"})," - Remaining requests today"]})]})]})]}),e.jsxs("div",{className:"mt-6",children:[e.jsx("h4",{className:"font-medium mb-4",children:"Endpoints"}),e.jsx("div",{className:"space-y-3",children:Pe.map((a,c)=>e.jsxs("div",{className:"rounded-lg border p-4",children:[e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(d,{variant:a.method==="GET"?"secondary":"default",className:"font-mono",children:a.method}),e.jsx("code",{className:"text-sm font-mono",children:a.path})]}),e.jsx("p",{className:"text-sm text-muted-foreground mb-2",children:a.description}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"Required scopes:"}),a.scopes.map(o=>e.jsx(d,{variant:"outline",className:"text-xs",children:o},o))]})]})}),e.jsxs("div",{className:"mt-3 pt-3 border-t",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Response"}),e.jsx("code",{className:"text-xs bg-muted px-2 py-1 rounded block",children:a.response})]})]},c))})]})]})]})}),e.jsxs(N,{value:"examples",className:"space-y-6",children:[e.jsxs(_,{children:[e.jsxs(b,{children:[e.jsxs(w,{className:"flex items-center gap-2",children:[e.jsx(le,{className:"h-5 w-5"}),"Quick Start"]}),e.jsx(C,{children:"Code examples in popular languages to get you started quickly"})]}),e.jsxs(k,{children:[e.jsxs(S,{defaultValue:"curl",className:"space-y-4",children:[e.jsxs(L,{children:[e.jsx(p,{value:"curl",children:"cURL"}),e.jsx(p,{value:"javascript",children:"JavaScript"}),e.jsx(p,{value:"python",children:"Python"})]}),Object.entries(De).map(([a,c])=>e.jsx(N,{value:a,children:e.jsx("pre",{className:"bg-muted rounded-lg p-4 overflow-x-auto",children:e.jsx("code",{className:"text-sm",children:c})})},a))]}),e.jsxs("div",{className:"mt-6 space-y-4",children:[e.jsx("h4",{className:"font-medium",children:"Response Example"}),e.jsx("pre",{className:"bg-muted rounded-lg p-4 overflow-x-auto",children:e.jsx("code",{className:"text-sm",children:`{
27  "success": true,
28  "data": {
29    "hourly_predictions": [
30      { "hour": 6, "predicted_sales": 245.50, "predicted_traffic": 12 },
31      { "hour": 7, "predicted_sales": 520.00, "predicted_traffic": 28 },
32      { "hour": 8, "predicted_sales": 890.25, "predicted_traffic": 45 }
33    ],
34    "weather_impact": {
35      "score": 0.85,
36      "conditions": "partly cloudy",
37      "temperature": 72
38    },
39    "confidence_score": 0.92
40  },
41  "meta": {
42    "store_id": "abc123",
43    "generated_at": "2024-01-15T06:00:00Z"
44  }
45}`})}),e.jsx("h4",{className:"font-medium",children:"Error Response"}),e.jsx("pre",{className:"bg-muted rounded-lg p-4 overflow-x-auto",children:e.jsx("code",{className:"text-sm",children:`{
46  "success": false,
47  "error": {
48    "code": "RATE_LIMIT_EXCEEDED",
49    "message": "Rate limit exceeded. Try again in 45 seconds.",
50    "remaining": {
51      "minute": 0,
52      "day": 9856
53    }
54  }
55}`})})]})]})]}),e.jsxs(_,{children:[e.jsxs(b,{children:[e.jsx(w,{children:"Webhooks"}),e.jsx(C,{children:"Receive real-time notifications for important events"})]}),e.jsx(k,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Configure webhook endpoints to receive notifications when events occur:"}),e.jsxs("ul",{className:"space-y-2 text-sm",children:[e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx(d,{variant:"outline",children:"inventory.low_stock"}),e.jsx("span",{className:"text-muted-foreground",children:"Ingredient falls below reorder level"})]}),e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx(d,{variant:"outline",children:"order.created"}),e.jsx("span",{className:"text-muted-foreground",children:"New purchase order created"})]}),e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx(d,{variant:"outline",children:"forecast.generated"}),e.jsx("span",{className:"text-muted-foreground",children:"Daily forecast is ready"})]}),e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx(d,{variant:"outline",children:"autonomous.action"}),e.jsx("span",{className:"text-muted-foreground",children:"Autonomous mode took an action"})]})]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-4",children:"Contact support to configure webhook endpoints for your organization."})]})})]})]})]})]})})}export{ze as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.