@nebulit/embuilder 0.1.44 → 0.1.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebulit/embuilder",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "Event-model driven development toolkit for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,12 +11,6 @@ If the processors-array in the slice json is not empty. Treat this as an AUTOMAT
11
11
 
12
12
  ## Critical Requirements
13
13
 
14
- ### Restaurant ID Requirement
15
- - **CRITICAL**: ALL database tables MUST have a `restaurant_id` column (snake_case)
16
- - **CRITICAL**: ALL events MUST have `restaurantId` in their metadata (camelCase)
17
- - **NEVER** use `locationId` or `location_id` - these are outdated and forbidden
18
- - This ensures proper multi-tenancy and data isolation
19
-
20
14
  ## Implementation Steps
21
15
 
22
16
  When creating a state-view slice, you MUST create the following files:
@@ -77,7 +77,7 @@ Slice C: { groupId: "123", sliceType: "STATE_CHANGE", title: "Cancel Event" }
77
77
  ```typescript
78
78
  // AuthContext: user, session, restaurantId
79
79
  import { useAuth } from "@/contexts/AuthContext";
80
- const { user, session, restaurantId } = useAuth();
80
+ const { user, session } = useAuth();
81
81
 
82
82
  // ApiContext: token, restaurantId, userId (auto-injected into headers)
83
83
  import { useApiContext } from "@/hooks/useApiContext";
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ prompt() {
5
+ local var_name="$1"
6
+ local prompt_text="$2"
7
+ local value
8
+ read -rp "$prompt_text: " value
9
+ if [[ -z "$value" ]]; then
10
+ echo "Error: $var_name cannot be empty." >&2
11
+ exit 1
12
+ fi
13
+ echo "$value"
14
+ }
15
+
16
+ prompt_secret() {
17
+ local var_name="$1"
18
+ local prompt_text="$2"
19
+ local value
20
+ read -rsp "$prompt_text: " value
21
+ echo "" >&2
22
+ if [[ -z "$value" ]]; then
23
+ echo "Error: $var_name cannot be empty." >&2
24
+ exit 1
25
+ fi
26
+ echo "$value"
27
+ }
28
+
29
+ echo "=== Supabase .env setup ==="
30
+ echo ""
31
+
32
+ PROJECT_ID=$(prompt SUPABASE_PROJECT_ID "Supabase Project ID")
33
+ DB_PASSWORD=$(prompt_secret SUPABASE_DB_PASSWORD "Database Password")
34
+ PUBLISHABLE_KEY=$(prompt_secret SUPABASE_PUBLISHABLE_KEY "Supabase Publishable Key")
35
+ #SECRET_KEY=$(prompt_secret SUPABASE_SECRET_KEY "Supabase Secret Key")
36
+
37
+ cat > .env.development <<EOF
38
+ VITE_SUPABASE_URL=https://${PROJECT_ID}.supabase.co
39
+ VITE_SUPABASE_PUBLISHABLE_KEY=${PUBLISHABLE_KEY}
40
+ VITE_SUPABASE_DB_URL=postgresql://postgres.${PROJECT_ID}:${DB_PASSWORD}@aws-1-eu-central-1.pooler.supabase.com:5432/postgres?prepareThreshold=0
41
+
42
+ echo ""
43
+ echo ".env.development created successfully."
@@ -6,12 +6,6 @@ import {AuthProvider} from "@/contexts/AuthContext";
6
6
  import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
7
7
  import {BrowserRouter, Routes, Route} from "react-router-dom";
8
8
  import Dashboard from "./pages/Dashboard";
9
- import Tables from "./pages/Tables";
10
- import Staff from "./pages/Staff";
11
- import Shifts from "./pages/Shifts";
12
- import Tasks from "./pages/Tasks";
13
- import Menus from "./pages/Menus";
14
- import Vacations from "./pages/Vacations";
15
9
  import NotFound from "./pages/NotFound";
16
10
  import Auth from "@/pages/Auth.tsx";
17
11
  import Register from "@/pages/Register.tsx";
@@ -22,24 +16,18 @@ const queryClient = new QueryClient();
22
16
  const App = () => (
23
17
  <QueryClientProvider client={queryClient}>
24
18
  <AuthProvider>
25
- <TooltipProvider>
26
- <Toaster/>
27
- <Sonner/>
28
- <BrowserRouter>
29
- <Routes>
30
- <Route path="/register" element={<Register/>}/>
31
- <Route path="/auth" element={<Auth/>}/>
32
- <Route path="/" element={<ProtectedRoute><Dashboard/></ProtectedRoute>}/>
33
- <Route path="/tables" element={<ProtectedRoute><Tables/></ProtectedRoute>}/>
34
- <Route path="/staff" element={<ProtectedRoute><Staff/></ProtectedRoute>}/>
35
- <Route path="/shifts" element={<ProtectedRoute><Shifts/></ProtectedRoute>}/>
36
- <Route path="/tasks" element={<ProtectedRoute><Tasks/></ProtectedRoute>}/>
37
- <Route path="/menus" element={<ProtectedRoute><Menus/></ProtectedRoute>}/>
38
- <Route path="/vacations" element={<ProtectedRoute><Vacations/></ProtectedRoute>}/>
39
- <Route path="*" element={<NotFound/>}/>
40
- </Routes>
41
- </BrowserRouter>
42
- </TooltipProvider>
19
+ <TooltipProvider>
20
+ <Toaster/>
21
+ <Sonner/>
22
+ <BrowserRouter>
23
+ <Routes>
24
+ <Route path="/register" element={<Register/>}/>
25
+ <Route path="/auth" element={<Auth/>}/>
26
+ <Route path="/" element={<ProtectedRoute><Dashboard/></ProtectedRoute>}/>
27
+ <Route path="*" element={<NotFound/>}/>
28
+ </Routes>
29
+ </BrowserRouter>
30
+ </TooltipProvider>
43
31
  </AuthProvider>
44
32
  </QueryClientProvider>
45
33
  );
@@ -4,133 +4,95 @@
4
4
  const DEFAULT_API_URL = import.meta.env.VITE_BASE_URL ?? "http://localhost:3000";
5
5
 
6
6
  export const getApiUrl = (): string => {
7
- return DEFAULT_API_URL;
7
+ return DEFAULT_API_URL;
8
8
  };
9
9
 
10
10
  export const setApiUrl = (url: string): void => {
11
- localStorage.setItem("api_base_url", url);
11
+ localStorage.setItem("api_base_url", url);
12
12
  };
13
13
 
14
14
  export interface ApiContext {
15
- token: string;
16
- tenantId?: string;
17
- userId?: string;
15
+ token: string;
16
+ tenantId?: string;
17
+ userId?: string;
18
18
  }
19
19
 
20
20
  interface ApiRequestOptions {
21
- method?: "GET" | "POST" | "PUT" | "DELETE";
22
- body?: unknown;
23
- headers?: Record<string, string>;
24
- correlationId?: string;
21
+ method?: "GET" | "POST" | "PUT" | "DELETE";
22
+ body?: unknown;
23
+ headers?: Record<string, string>;
24
+ correlationId?: string;
25
25
  }
26
26
 
27
27
  interface ApiResponse<T> {
28
- data?: T;
29
- error?: string;
30
- ok: boolean;
28
+ data?: T;
29
+ error?: string;
30
+ ok: boolean;
31
31
  }
32
32
 
33
33
  export async function apiRequest<T>(
34
- endpoint: string,
35
- ctx: ApiContext,
36
- options: ApiRequestOptions = {}
34
+ endpoint: string,
35
+ ctx: ApiContext,
36
+ options: ApiRequestOptions = {}
37
37
  ): Promise<ApiResponse<T>> {
38
- const { method = "GET", body, headers = {}, correlationId } = options;
38
+ const {method = "GET", body, headers = {}, correlationId} = options;
39
39
 
40
- const baseUrl = getApiUrl();
40
+ const baseUrl = getApiUrl();
41
41
 
42
- const requestHeaders: Record<string, string> = {
43
- "Content-Type": "application/json",
44
- ...headers,
45
- };
46
-
47
- if (ctx.token) {
48
- requestHeaders["Authorization"] = `Bearer ${ctx.token}`;
49
- }
50
-
51
- if (ctx.tenantId) {
52
- requestHeaders["x-tenant-id"] = ctx.tenantId;
53
- }
54
-
55
- if (ctx.userId) {
56
- requestHeaders["x-user-id"] = ctx.userId;
57
- }
58
-
59
- if (correlationId) {
60
- requestHeaders["correlation_id"] = correlationId;
61
- }
42
+ const requestHeaders: Record<string, string> = {
43
+ "Content-Type": "application/json",
44
+ ...headers,
45
+ };
62
46
 
63
- try {
64
- const response = await fetch(`${baseUrl}${endpoint}`, {
65
- method,
66
- headers: requestHeaders,
67
- body: body ? JSON.stringify(body) : undefined,
68
- });
47
+ if (ctx.token) {
48
+ requestHeaders["Authorization"] = `Bearer ${ctx.token}`;
49
+ }
69
50
 
70
- const data = await response.json();
71
51
 
72
- if (!response.ok) {
73
- return {
74
- ok: false,
75
- error: data.error || `HTTP ${response.status}: ${response.statusText}`,
76
- };
52
+ if (ctx.userId) {
53
+ requestHeaders["x-user-id"] = ctx.userId;
54
+ }
55
+ /**
56
+ * if (ctx.tenantId) {
57
+ * requestHeaders["x-tenant-id"] = ctx.tenantId;
58
+ * }
59
+ */
60
+
61
+ if (correlationId) {
62
+ requestHeaders["correlation_id"] = correlationId;
77
63
  }
78
64
 
79
- return { ok: true, data };
80
- } catch (error) {
81
- return {
82
- ok: false,
83
- error: error instanceof Error ? error.message : "Network error",
84
- };
85
- }
65
+ try {
66
+ const response = await fetch(`${baseUrl}${endpoint}`, {
67
+ method,
68
+ headers: requestHeaders,
69
+ body: body ? JSON.stringify(body) : undefined,
70
+ });
71
+
72
+ const data = await response.json();
73
+
74
+ if (!response.ok) {
75
+ return {
76
+ ok: false,
77
+ error: data.error || `HTTP ${response.status}: ${response.statusText}`,
78
+ };
79
+ }
80
+
81
+ return {ok: true, data};
82
+ } catch (error) {
83
+ return {
84
+ ok: false,
85
+ error: error instanceof Error ? error.message : "Network error",
86
+ };
87
+ }
86
88
  }
87
89
 
88
90
  // Query endpoints (GET)
89
91
  export const queryEndpoints = {
90
- tables: "/api/query/tables-collection",
91
- shifts: "/api/query/shifts-collection",
92
- clerks: "/api/query/clerks-collection",
93
- clerksToInvite: "/api/query/clerkstoinvite-collection",
94
- tasks: "/api/query/tasks-collection",
95
- menus: "/api/query/uploadedmenus-collection",
96
- serviceDays: "/api/query/servicedays-collection",
97
- timeslots: "/api/query/configuredtimeslots-collection",
98
- vacations: "/api/query/plannedvacations-collection",
99
- shiftAssignments: "/api/query/shiftassignments-collection",
100
- shiftsForAssignments: "/api/query/shiftsforassignments-collection",
101
- images: "/api/query/uploadedimages-collection",
92
+ //tables: "/api/query/tables-collection",
102
93
  };
103
94
 
104
95
  // Command endpoints (POST)
105
96
  export const commandEndpoints = {
106
- registerRestaurant: "/api/register-restaurant",
107
- addTable: "/api/addtable",
108
- updateTable: "/api/updatetable",
109
- removeTable: "/api/removetable",
110
- blockTableReservation: "/api/blocktablereservation",
111
- unblockTableReservation: "/api/unblocktablereservation",
112
- createShift: "/api/createshift",
113
- activateShift: "/api/activateshift",
114
- deleteShift: "/api/deleteshift",
115
- assignShift: "/api/assignshift",
116
- unassignShift: "/api/unassignshift",
117
- registerClerk: "/api/registerclerk",
118
- deactivateClerk: "/api/deactivateclerk",
119
- removeClerk: "/api/removeclerk",
120
- confirmInvitation: "/api/confirminvitation",
121
-
122
- updateTask: "/api/updatetask",
123
- deleteTask: "/api/deletetask",
124
- uploadMenu: "/api/uploadmenu",
125
- deleteMenu: "/api/deletemenu",
126
- uploadImage: "/api/uploadimage",
127
- cancelReservation: "/api/cancelreservation",
128
- addServiceDay: "/api/addserviceday",
129
- configureTimeslot: "/api/configuretimeslot",
130
- planVacation: "/api/planvacation",
131
- cancelVacation: "/api/cancelvacation",
132
- activateOnlineReservation: "/api/activateonlinereservation",
133
- deactivateOnlineReservation: "/api/deactivateonlinereservation",
134
- registerNoShow: "/api/registernoshow",
135
- registerShowUp: "/api/registershowup",
97
+ //addTable: "/api/addtable",
136
98
  };