@l4yercak3/cli 1.0.6 → 1.1.1
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/bin/cli.js +6 -0
- package/docs/microsass_production_machine/CLI_API_REFERENCE.md +1197 -0
- package/docs/microsass_production_machine/CLI_PRODUCT_VISION.md +676 -0
- package/docs/microsass_production_machine/CLI_REQUIREMENTS.md +606 -0
- package/docs/microsass_production_machine/CONNECTED_APPLICATIONS_SPEC.md +390 -0
- package/docs/microsass_production_machine/IMPLEMENTATION_ROADMAP.md +725 -0
- package/docs/microsass_production_machine/OBJECT_MAPPINGS.md +808 -0
- package/docs/microsass_production_machine/REFERENCE_IMPLEMENTATION.md +532 -0
- package/package.json +1 -1
- package/src/api/backend-client.js +62 -0
- package/src/commands/spread.js +137 -12
- package/src/generators/api-client-generator.js +13 -6
- package/src/generators/env-generator.js +14 -1
- package/src/generators/index.js +4 -4
- package/src/generators/nextauth-generator.js +14 -9
- package/src/utils/file-utils.js +117 -0
- package/tests/api-client-generator.test.js +20 -13
- package/tests/backend-client.test.js +167 -0
- package/tests/file-utils.test.js +194 -0
- package/tests/generators-index.test.js +8 -0
- package/tests/nextauth-generator.test.js +38 -14
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
# CLI Requirements - What CLI Teams Need to Implement
|
|
2
|
+
|
|
3
|
+
**Purpose:** This document tells CLI teams exactly what to build to register and manage connected applications in L4YERCAK3.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The CLI needs to:
|
|
10
|
+
1. **Authenticate** users via browser OAuth flow
|
|
11
|
+
2. **Detect** project framework and models
|
|
12
|
+
3. **Register** the application with L4YERCAK3 backend
|
|
13
|
+
4. **Generate** API client code and types
|
|
14
|
+
5. **Sync** data between local app and L4YERCAK3
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Part 1: Authentication (Already Implemented)
|
|
19
|
+
|
|
20
|
+
CLI authentication is working. For reference:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
l4yercak3 login
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Flow:**
|
|
27
|
+
1. CLI opens browser to `https://l4yercak3.com/cli/login?state={uuid}`
|
|
28
|
+
2. User authenticates with L4YERCAK3
|
|
29
|
+
3. Backend creates CLI session token
|
|
30
|
+
4. Browser redirects to localhost callback OR user copies token
|
|
31
|
+
5. CLI stores token in `~/.l4yercak3/config.json`
|
|
32
|
+
|
|
33
|
+
**Token Format:** `cli_session_{64_hex_chars}`
|
|
34
|
+
**Token Lifetime:** 30 days
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Part 2: Application Registration (NEW - Priority 1)
|
|
39
|
+
|
|
40
|
+
### Command: `l4yercak3 init`
|
|
41
|
+
|
|
42
|
+
This is the main command CLI teams need to implement.
|
|
43
|
+
|
|
44
|
+
**What it does:**
|
|
45
|
+
1. Detects project framework
|
|
46
|
+
2. Asks user which features to enable
|
|
47
|
+
3. Registers application with L4YERCAK3 backend
|
|
48
|
+
4. Generates API client files
|
|
49
|
+
|
|
50
|
+
### Step 2.1: Project Detection
|
|
51
|
+
|
|
52
|
+
CLI must detect and collect:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
interface ProjectDetection {
|
|
56
|
+
// Framework detection
|
|
57
|
+
framework: "nextjs" | "remix" | "astro" | "vite" | "nuxt" | "sveltekit" | "other";
|
|
58
|
+
frameworkVersion?: string; // From package.json
|
|
59
|
+
hasTypeScript: boolean; // tsconfig.json exists
|
|
60
|
+
routerType?: "app" | "pages"; // For Next.js only
|
|
61
|
+
|
|
62
|
+
// Project identification
|
|
63
|
+
projectPath: string; // Absolute path
|
|
64
|
+
projectPathHash: string; // SHA256(projectPath) - for identifying returning projects
|
|
65
|
+
projectName: string; // From package.json name or directory name
|
|
66
|
+
|
|
67
|
+
// Database detection (optional)
|
|
68
|
+
hasFrontendDatabase: boolean;
|
|
69
|
+
frontendDatabaseType?: "convex" | "prisma" | "drizzle" | "other";
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Detection Logic:**
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Framework detection
|
|
77
|
+
if (existsSync('next.config.js') || existsSync('next.config.ts')) {
|
|
78
|
+
framework = 'nextjs';
|
|
79
|
+
routerType = existsSync('app/') ? 'app' : 'pages';
|
|
80
|
+
}
|
|
81
|
+
if (existsSync('remix.config.js')) framework = 'remix';
|
|
82
|
+
if (existsSync('astro.config.mjs')) framework = 'astro';
|
|
83
|
+
// etc.
|
|
84
|
+
|
|
85
|
+
// TypeScript detection
|
|
86
|
+
hasTypeScript = existsSync('tsconfig.json');
|
|
87
|
+
|
|
88
|
+
// Database detection
|
|
89
|
+
hasFrontendDatabase = existsSync('convex/') || existsSync('prisma/schema.prisma');
|
|
90
|
+
if (existsSync('convex/')) frontendDatabaseType = 'convex';
|
|
91
|
+
if (existsSync('prisma/')) frontendDatabaseType = 'prisma';
|
|
92
|
+
|
|
93
|
+
// Project hash for identification
|
|
94
|
+
projectPathHash = sha256(absolutePath);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 2.2: Feature Selection
|
|
98
|
+
|
|
99
|
+
CLI should prompt user for features:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
? Which L4YERCAK3 features do you want to use?
|
|
103
|
+
◉ CRM (contacts, organizations)
|
|
104
|
+
◉ Events (event management, registrations)
|
|
105
|
+
◉ Products (product catalog)
|
|
106
|
+
◉ Checkout (payment processing)
|
|
107
|
+
◉ Tickets (ticket generation)
|
|
108
|
+
◉ Invoicing (invoice creation)
|
|
109
|
+
◉ Forms (dynamic forms)
|
|
110
|
+
◉ Projects (project management)
|
|
111
|
+
◯ Workflows (automation)
|
|
112
|
+
◯ Templates (document templates)
|
|
113
|
+
◯ AI (AI assistant)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Result:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
const selectedFeatures: string[] = [
|
|
120
|
+
"crm", "events", "products", "checkout", "tickets", "invoicing", "forms"
|
|
121
|
+
];
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Step 2.3: API Registration
|
|
125
|
+
|
|
126
|
+
**Endpoint:** `POST /api/v1/cli/applications`
|
|
127
|
+
|
|
128
|
+
**Headers:**
|
|
129
|
+
```
|
|
130
|
+
Authorization: Bearer cli_session_xxx
|
|
131
|
+
Content-Type: application/json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Request Body:**
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
interface RegisterApplicationRequest {
|
|
138
|
+
// Organization (from login)
|
|
139
|
+
organizationId: string;
|
|
140
|
+
|
|
141
|
+
// Basic info
|
|
142
|
+
name: string; // Project name (user can edit)
|
|
143
|
+
description?: string; // Optional description
|
|
144
|
+
|
|
145
|
+
// Source detection
|
|
146
|
+
source: {
|
|
147
|
+
type: "cli";
|
|
148
|
+
projectPathHash: string; // SHA256 of absolute path
|
|
149
|
+
cliVersion: string; // "1.0.0"
|
|
150
|
+
framework: string; // "nextjs"
|
|
151
|
+
frameworkVersion?: string; // "15.0.0"
|
|
152
|
+
hasTypeScript: boolean;
|
|
153
|
+
routerType?: "app" | "pages";
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Connection config
|
|
157
|
+
connection: {
|
|
158
|
+
features: string[]; // ["crm", "events", "checkout"]
|
|
159
|
+
hasFrontendDatabase: boolean;
|
|
160
|
+
frontendDatabaseType?: string;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Optional: Model mappings if detected
|
|
164
|
+
modelMappings?: Array<{
|
|
165
|
+
localModel: string; // "User", "Event"
|
|
166
|
+
layerCakeType: string; // "contact", "event"
|
|
167
|
+
syncDirection: "push" | "pull" | "bidirectional" | "none";
|
|
168
|
+
confidence: number; // 0-100
|
|
169
|
+
isAutoDetected: boolean;
|
|
170
|
+
}>;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Response:**
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
interface RegisterApplicationResponse {
|
|
178
|
+
success: boolean;
|
|
179
|
+
applicationId: string; // ID of created connected_application
|
|
180
|
+
|
|
181
|
+
// API credentials
|
|
182
|
+
apiKey: {
|
|
183
|
+
id: string;
|
|
184
|
+
key: string; // Full key, only shown once: "org_xxx_sk_live_yyy"
|
|
185
|
+
prefix: string; // "org_xxx_sk_live_..."
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Backend URLs
|
|
189
|
+
backendUrl: string; // "https://agreeable-lion-828.convex.site"
|
|
190
|
+
|
|
191
|
+
// If application already exists (same projectPathHash)
|
|
192
|
+
existingApplication?: boolean;
|
|
193
|
+
message?: string;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Error Responses:**
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// 401 Unauthorized
|
|
201
|
+
{ error: "Invalid or expired CLI session", code: "INVALID_SESSION" }
|
|
202
|
+
|
|
203
|
+
// 400 Bad Request
|
|
204
|
+
{ error: "Missing required field: name", code: "VALIDATION_ERROR" }
|
|
205
|
+
|
|
206
|
+
// 409 Conflict (optional - if we want to prevent duplicates)
|
|
207
|
+
{
|
|
208
|
+
error: "Application already registered for this project",
|
|
209
|
+
code: "DUPLICATE_APPLICATION",
|
|
210
|
+
existingApplicationId: "app_xxx"
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Step 2.4: Check Existing Application
|
|
215
|
+
|
|
216
|
+
Before registering, CLI should check if app already exists:
|
|
217
|
+
|
|
218
|
+
**Endpoint:** `GET /api/v1/cli/applications/by-path?hash={projectPathHash}`
|
|
219
|
+
|
|
220
|
+
**Response:**
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface ExistingApplicationResponse {
|
|
224
|
+
found: boolean;
|
|
225
|
+
application?: {
|
|
226
|
+
id: string;
|
|
227
|
+
name: string;
|
|
228
|
+
status: string;
|
|
229
|
+
features: string[];
|
|
230
|
+
lastActivityAt: number;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
If found, CLI should ask: "Application already registered. Update it? (Y/n)"
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Part 3: Code Generation (Priority 2)
|
|
240
|
+
|
|
241
|
+
After registration, CLI generates files.
|
|
242
|
+
|
|
243
|
+
### Files to Generate
|
|
244
|
+
|
|
245
|
+
**1. API Client: `src/lib/layercake.ts`**
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// Auto-generated by L4YERCAK3 CLI v1.0.0
|
|
249
|
+
// Do not edit manually - run `l4yercak3 generate` to regenerate
|
|
250
|
+
|
|
251
|
+
const API_URL = process.env.NEXT_PUBLIC_L4YERCAK3_URL!;
|
|
252
|
+
const API_KEY = process.env.NEXT_PUBLIC_L4YERCAK3_KEY!;
|
|
253
|
+
const ORG_ID = process.env.NEXT_PUBLIC_L4YERCAK3_ORG_ID!;
|
|
254
|
+
|
|
255
|
+
async function apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
|
256
|
+
const response = await fetch(`${API_URL}${endpoint}`, {
|
|
257
|
+
...options,
|
|
258
|
+
headers: {
|
|
259
|
+
'Content-Type': 'application/json',
|
|
260
|
+
'Authorization': `Bearer ${API_KEY}`,
|
|
261
|
+
...options.headers,
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
if (!response.ok) {
|
|
266
|
+
const error = await response.json().catch(() => ({}));
|
|
267
|
+
throw new Error(error.message || `API Error: ${response.status}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return response.json();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Feature modules based on selection...
|
|
274
|
+
export const eventApi = { /* ... */ };
|
|
275
|
+
export const crmApi = { /* ... */ };
|
|
276
|
+
// etc.
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**2. Types: `src/types/layercake.ts`**
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
// Auto-generated by L4YERCAK3 CLI v1.0.0
|
|
283
|
+
|
|
284
|
+
export interface Event {
|
|
285
|
+
id: string;
|
|
286
|
+
name: string;
|
|
287
|
+
description?: string;
|
|
288
|
+
status: string;
|
|
289
|
+
startDate?: number;
|
|
290
|
+
endDate?: number;
|
|
291
|
+
// ...
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export interface Contact {
|
|
295
|
+
id: string;
|
|
296
|
+
email: string;
|
|
297
|
+
firstName?: string;
|
|
298
|
+
lastName?: string;
|
|
299
|
+
// ...
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Types for each enabled feature...
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**3. Environment: `.env.local.example`**
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# L4YERCAK3 Backend - Generated by CLI
|
|
309
|
+
NEXT_PUBLIC_L4YERCAK3_URL=https://agreeable-lion-828.convex.site
|
|
310
|
+
NEXT_PUBLIC_L4YERCAK3_KEY=your_api_key_here
|
|
311
|
+
NEXT_PUBLIC_L4YERCAK3_ORG_ID=org_xxx
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**4. Update actual `.env.local`**
|
|
315
|
+
|
|
316
|
+
CLI should either:
|
|
317
|
+
- Append to existing `.env.local` with comments
|
|
318
|
+
- Ask user permission before modifying
|
|
319
|
+
|
|
320
|
+
### Generation Templates
|
|
321
|
+
|
|
322
|
+
CLI needs templates for each feature. Store in CLI package:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
cli/
|
|
326
|
+
├── templates/
|
|
327
|
+
│ ├── api-client.ts.hbs # Handlebars template
|
|
328
|
+
│ ├── types/
|
|
329
|
+
│ │ ├── event.ts.hbs
|
|
330
|
+
│ │ ├── contact.ts.hbs
|
|
331
|
+
│ │ ├── product.ts.hbs
|
|
332
|
+
│ │ └── ...
|
|
333
|
+
│ └── hooks/
|
|
334
|
+
│ ├── use-events.ts.hbs
|
|
335
|
+
│ └── ...
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Part 4: Update Application (Priority 3)
|
|
341
|
+
|
|
342
|
+
### Command: `l4yercak3 update`
|
|
343
|
+
|
|
344
|
+
Re-runs detection and updates backend.
|
|
345
|
+
|
|
346
|
+
**Endpoint:** `PATCH /api/v1/cli/applications/:id`
|
|
347
|
+
|
|
348
|
+
**Request:**
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
interface UpdateApplicationRequest {
|
|
352
|
+
// Any fields from RegisterApplicationRequest
|
|
353
|
+
name?: string;
|
|
354
|
+
description?: string;
|
|
355
|
+
connection?: {
|
|
356
|
+
features?: string[];
|
|
357
|
+
};
|
|
358
|
+
modelMappings?: ModelMapping[];
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Part 5: Sync Status (Priority 3)
|
|
365
|
+
|
|
366
|
+
### Command: `l4yercak3 status`
|
|
367
|
+
|
|
368
|
+
Shows connection status and sync info.
|
|
369
|
+
|
|
370
|
+
**Endpoint:** `GET /api/v1/cli/applications/:id`
|
|
371
|
+
|
|
372
|
+
**Response:**
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
interface ApplicationStatusResponse {
|
|
376
|
+
id: string;
|
|
377
|
+
name: string;
|
|
378
|
+
status: "active" | "paused" | "disconnected";
|
|
379
|
+
|
|
380
|
+
connection: {
|
|
381
|
+
features: string[];
|
|
382
|
+
apiKeyPrefix: string;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
sync: {
|
|
386
|
+
enabled: boolean;
|
|
387
|
+
lastSyncAt?: number;
|
|
388
|
+
lastSyncStatus?: "success" | "partial" | "failed";
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
deployment?: {
|
|
392
|
+
productionUrl?: string;
|
|
393
|
+
stagingUrl?: string;
|
|
394
|
+
deploymentStatus: string;
|
|
395
|
+
lastDeployedAt?: number;
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
cli: {
|
|
399
|
+
registeredAt: number;
|
|
400
|
+
lastActivityAt: number;
|
|
401
|
+
generatedFiles: Array<{
|
|
402
|
+
path: string;
|
|
403
|
+
type: string;
|
|
404
|
+
generatedAt: number;
|
|
405
|
+
}>;
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Command: `l4yercak3 sync`
|
|
411
|
+
|
|
412
|
+
Syncs data between local and backend.
|
|
413
|
+
|
|
414
|
+
**Endpoint:** `POST /api/v1/cli/applications/:id/sync`
|
|
415
|
+
|
|
416
|
+
**Request:**
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
interface SyncRequest {
|
|
420
|
+
direction: "push" | "pull" | "bidirectional";
|
|
421
|
+
models?: string[]; // Optional: specific models to sync
|
|
422
|
+
dryRun?: boolean; // Preview without making changes
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Response:**
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
interface SyncResponse {
|
|
430
|
+
success: boolean;
|
|
431
|
+
direction: string;
|
|
432
|
+
results: Array<{
|
|
433
|
+
model: string;
|
|
434
|
+
recordsProcessed: number;
|
|
435
|
+
recordsCreated: number;
|
|
436
|
+
recordsUpdated: number;
|
|
437
|
+
errors: number;
|
|
438
|
+
}>;
|
|
439
|
+
duration: number;
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Part 6: Model Detection (Priority 4)
|
|
446
|
+
|
|
447
|
+
### Detecting Local Models
|
|
448
|
+
|
|
449
|
+
CLI should detect models from:
|
|
450
|
+
|
|
451
|
+
**Prisma:**
|
|
452
|
+
```typescript
|
|
453
|
+
// Parse prisma/schema.prisma
|
|
454
|
+
model User {
|
|
455
|
+
id String @id @default(cuid())
|
|
456
|
+
email String @unique
|
|
457
|
+
firstName String?
|
|
458
|
+
lastName String?
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**TypeScript interfaces:**
|
|
463
|
+
```typescript
|
|
464
|
+
// Scan src/types/*.ts for interface definitions
|
|
465
|
+
interface User {
|
|
466
|
+
id: string;
|
|
467
|
+
email: string;
|
|
468
|
+
firstName?: string;
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Mapping to L4YERCAK3 Types
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
const TYPE_MAPPINGS = {
|
|
476
|
+
// Model name patterns → L4YERCAK3 type
|
|
477
|
+
'user': 'contact',
|
|
478
|
+
'customer': 'contact',
|
|
479
|
+
'member': 'contact',
|
|
480
|
+
'company': 'crm_organization',
|
|
481
|
+
'organization': 'crm_organization',
|
|
482
|
+
'event': 'event',
|
|
483
|
+
'meeting': 'event',
|
|
484
|
+
'product': 'product',
|
|
485
|
+
'item': 'product',
|
|
486
|
+
'order': 'transaction',
|
|
487
|
+
'invoice': 'invoice',
|
|
488
|
+
'ticket': 'ticket',
|
|
489
|
+
'form': 'form',
|
|
490
|
+
'project': 'project',
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
function detectModelMapping(localModel: string): {
|
|
494
|
+
layerCakeType: string;
|
|
495
|
+
confidence: number;
|
|
496
|
+
} {
|
|
497
|
+
const normalized = localModel.toLowerCase();
|
|
498
|
+
|
|
499
|
+
for (const [pattern, type] of Object.entries(TYPE_MAPPINGS)) {
|
|
500
|
+
if (normalized.includes(pattern)) {
|
|
501
|
+
return { layerCakeType: type, confidence: 80 };
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return { layerCakeType: 'unknown', confidence: 0 };
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Summary: Implementation Priority
|
|
512
|
+
|
|
513
|
+
### Week 1-2: Core Registration
|
|
514
|
+
|
|
515
|
+
1. **`l4yercak3 init`** command
|
|
516
|
+
- Project detection (framework, TypeScript, databases)
|
|
517
|
+
- Feature selection prompt
|
|
518
|
+
- API call to register application
|
|
519
|
+
- Basic code generation (API client + types)
|
|
520
|
+
|
|
521
|
+
2. **Backend endpoints** (we build these)
|
|
522
|
+
- `POST /api/v1/cli/applications`
|
|
523
|
+
- `GET /api/v1/cli/applications/by-path`
|
|
524
|
+
|
|
525
|
+
### Week 3-4: Status & Updates
|
|
526
|
+
|
|
527
|
+
3. **`l4yercak3 status`** command
|
|
528
|
+
- Show application status
|
|
529
|
+
- Show connected features
|
|
530
|
+
- Show last sync time
|
|
531
|
+
|
|
532
|
+
4. **`l4yercak3 update`** command
|
|
533
|
+
- Re-run detection
|
|
534
|
+
- Update features
|
|
535
|
+
- Regenerate code
|
|
536
|
+
|
|
537
|
+
5. **Backend endpoints**
|
|
538
|
+
- `GET /api/v1/cli/applications/:id`
|
|
539
|
+
- `PATCH /api/v1/cli/applications/:id`
|
|
540
|
+
|
|
541
|
+
### Week 5-6: Sync & Models
|
|
542
|
+
|
|
543
|
+
6. **`l4yercak3 sync`** command
|
|
544
|
+
- Push/pull data
|
|
545
|
+
- Dry run mode
|
|
546
|
+
|
|
547
|
+
7. **Model detection**
|
|
548
|
+
- Prisma schema parsing
|
|
549
|
+
- TypeScript interface detection
|
|
550
|
+
- Mapping suggestions
|
|
551
|
+
|
|
552
|
+
8. **Backend endpoints**
|
|
553
|
+
- `POST /api/v1/cli/applications/:id/sync`
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## CLI Team Deliverables Checklist
|
|
558
|
+
|
|
559
|
+
### Phase 1 (Start Now)
|
|
560
|
+
|
|
561
|
+
- [ ] **Project detection function** - Detect framework, TypeScript, databases
|
|
562
|
+
- [ ] **Project hash function** - SHA256 of absolute path
|
|
563
|
+
- [ ] **Feature selection UI** - Multi-select prompt for features
|
|
564
|
+
- [ ] **Register application API call** - POST to `/api/v1/cli/applications`
|
|
565
|
+
- [ ] **Check existing application** - GET `/api/v1/cli/applications/by-path`
|
|
566
|
+
- [ ] **API client template** - Generate `layercake.ts`
|
|
567
|
+
- [ ] **Types template** - Generate `layercake.types.ts`
|
|
568
|
+
- [ ] **Env file handling** - Create/update `.env.local`
|
|
569
|
+
|
|
570
|
+
### Phase 2 (After Phase 1)
|
|
571
|
+
|
|
572
|
+
- [ ] **Status command** - Show application status
|
|
573
|
+
- [ ] **Update command** - Update application config
|
|
574
|
+
- [ ] **Regenerate command** - Regenerate files from templates
|
|
575
|
+
|
|
576
|
+
### Phase 3 (After Phase 2)
|
|
577
|
+
|
|
578
|
+
- [ ] **Sync command** - Push/pull data
|
|
579
|
+
- [ ] **Model detection** - Parse Prisma/TypeScript
|
|
580
|
+
- [ ] **Mapping suggestions** - Auto-suggest model mappings
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Questions for CLI Team
|
|
585
|
+
|
|
586
|
+
1. **Config storage location?** Currently `~/.l4yercak3/config.json` - is this correct?
|
|
587
|
+
2. **Multiple organizations?** How should CLI handle users with access to multiple orgs?
|
|
588
|
+
3. **Offline mode?** Should CLI work offline with cached data?
|
|
589
|
+
4. **Interactive vs flags?** Support both `l4yercak3 init` (interactive) and `l4yercak3 init --features=crm,events` (flags)?
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## Backend Endpoints We Need to Build
|
|
594
|
+
|
|
595
|
+
For CLI teams to work, we need to implement these endpoints:
|
|
596
|
+
|
|
597
|
+
| Endpoint | Method | Priority | Description |
|
|
598
|
+
|----------|--------|----------|-------------|
|
|
599
|
+
| `/api/v1/cli/applications` | POST | P1 | Register new application |
|
|
600
|
+
| `/api/v1/cli/applications/by-path` | GET | P1 | Find by project hash |
|
|
601
|
+
| `/api/v1/cli/applications/:id` | GET | P2 | Get application details |
|
|
602
|
+
| `/api/v1/cli/applications/:id` | PATCH | P2 | Update application |
|
|
603
|
+
| `/api/v1/cli/applications/:id/sync` | POST | P3 | Trigger/report sync |
|
|
604
|
+
| `/api/v1/cli/applications` | GET | P2 | List all applications |
|
|
605
|
+
|
|
606
|
+
**These endpoints will be built in parallel with CLI work.**
|