create-bw-app 0.10.0 → 0.10.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/package.json +1 -1
- package/src/constants.mjs +6 -7
- package/src/generator.mjs +2 -4
- package/template/base/AGENTS.md +2 -0
- package/template/base/app/globals.css +29 -14
- package/template/base/app/page.tsx +1 -0
- package/template/base/config/brand.ts +0 -2
- package/template/base/config/modules.ts +1 -1
- package/template/base/docs/ai/README.md +3 -1
- package/template/base/docs/ai/examples.md +2 -0
- package/template/supabase/modules/crm/README.md +2 -0
- package/template/supabase/modules/crm/migrations/20260421201523_portal_read_indexes.sql +22 -0
- package/template/supabase/modules/projects/migrations/20260421201528_portal_read_indexes.sql +6 -0
package/package.json
CHANGED
package/src/constants.mjs
CHANGED
|
@@ -67,12 +67,12 @@ export const MODULE_STARTER_FILES = {
|
|
|
67
67
|
|
|
68
68
|
export const APP_DEPENDENCY_DEFAULTS = {
|
|
69
69
|
"@brightweblabs/app-shell": "^0.3.0",
|
|
70
|
-
"@brightweblabs/core-auth": "^0.3.
|
|
71
|
-
"@brightweblabs/infra": "^0.
|
|
72
|
-
"@brightweblabs/module-admin": "^0.3.
|
|
73
|
-
"@brightweblabs/module-crm": "^0.3.
|
|
74
|
-
"@brightweblabs/module-projects": "^0.
|
|
75
|
-
"@brightweblabs/ui": "^0.3.
|
|
70
|
+
"@brightweblabs/core-auth": "^0.3.3",
|
|
71
|
+
"@brightweblabs/infra": "^0.3.0",
|
|
72
|
+
"@brightweblabs/module-admin": "^0.3.2",
|
|
73
|
+
"@brightweblabs/module-crm": "^0.3.3",
|
|
74
|
+
"@brightweblabs/module-projects": "^0.3.2",
|
|
75
|
+
"@brightweblabs/ui": "^0.3.1",
|
|
76
76
|
"lucide-react": "^0.562.0",
|
|
77
77
|
"next": "16.1.6",
|
|
78
78
|
"react": "19.2.3",
|
|
@@ -110,7 +110,6 @@ export const DEFAULTS = {
|
|
|
110
110
|
tagline: "A configurable Brightweb starter app for new client instances.",
|
|
111
111
|
contactEmail: "hello@example.com",
|
|
112
112
|
supportEmail: "support@example.com",
|
|
113
|
-
primaryHex: "#1f7a45",
|
|
114
113
|
};
|
|
115
114
|
|
|
116
115
|
export const HELP_TEXT = `
|
package/src/generator.mjs
CHANGED
|
@@ -270,7 +270,6 @@ function createDerivedBrandValues(slug) {
|
|
|
270
270
|
tagline: DEFAULTS.tagline,
|
|
271
271
|
contactEmail: DEFAULTS.contactEmail,
|
|
272
272
|
supportEmail: DEFAULTS.supportEmail,
|
|
273
|
-
primaryHex: DEFAULTS.primaryHex,
|
|
274
273
|
};
|
|
275
274
|
}
|
|
276
275
|
|
|
@@ -283,7 +282,6 @@ function createPlatformBrandConfigFile({ slug, brandValues }) {
|
|
|
283
282
|
" tagline: string;",
|
|
284
283
|
" contactEmail: string;",
|
|
285
284
|
" supportEmail: string;",
|
|
286
|
-
" primaryHex: string;",
|
|
287
285
|
"};",
|
|
288
286
|
"",
|
|
289
287
|
"export const starterBrandConfig: StarterBrandConfig = {",
|
|
@@ -293,7 +291,6 @@ function createPlatformBrandConfigFile({ slug, brandValues }) {
|
|
|
293
291
|
` tagline: ${JSON.stringify(brandValues.tagline)},`,
|
|
294
292
|
` contactEmail: ${JSON.stringify(brandValues.contactEmail)},`,
|
|
295
293
|
` supportEmail: ${JSON.stringify(brandValues.supportEmail)},`,
|
|
296
|
-
` primaryHex: ${JSON.stringify(brandValues.primaryHex)},`,
|
|
297
294
|
"};",
|
|
298
295
|
"",
|
|
299
296
|
].join("\n");
|
|
@@ -328,7 +325,7 @@ export function createPlatformModulesConfigFile(selectedModules) {
|
|
|
328
325
|
" {",
|
|
329
326
|
' key: "crm",',
|
|
330
327
|
' label: "CRM",',
|
|
331
|
-
' description: "Contacts
|
|
328
|
+
' description: "Contacts and CRM server/data layer, with marketing-adjacent operational data stored in Supabase.",',
|
|
332
329
|
` enabled: ${String(selected.has("crm"))},`,
|
|
333
330
|
' packageName: "@brightweblabs/module-crm",',
|
|
334
331
|
' playgroundHref: "/playground/crm",',
|
|
@@ -636,6 +633,7 @@ export function createAppContextFile({
|
|
|
636
633
|
"AGENTS.md",
|
|
637
634
|
"docs/ai/README.md",
|
|
638
635
|
"README.md",
|
|
636
|
+
"app/globals.css",
|
|
639
637
|
"config/brand.ts",
|
|
640
638
|
"config/modules.ts",
|
|
641
639
|
"config/client.ts",
|
package/template/base/AGENTS.md
CHANGED
|
@@ -10,6 +10,7 @@ This generated project is a BrightWeb platform starter. Use this file as the loc
|
|
|
10
10
|
- `docs/ai/app-context.json`: machine-readable app summary for quick discovery.
|
|
11
11
|
- `components/`: local app components used by starter routes and future product surfaces.
|
|
12
12
|
- `config/brand.ts`: client identity, naming, and contact defaults.
|
|
13
|
+
- `app/globals.css`: global design tokens, theme mapping, and shared visual styling.
|
|
13
14
|
- `config/modules.ts`: selected module set and runtime enablement.
|
|
14
15
|
- `config/client.ts`: starter-facing derived state used by the home page and setup surfaces.
|
|
15
16
|
- `.env.local`: runtime service values for local development.
|
|
@@ -17,6 +18,7 @@ This generated project is a BrightWeb platform starter. Use this file as the loc
|
|
|
17
18
|
## Working rules
|
|
18
19
|
|
|
19
20
|
- Treat `/bootstrap`, `/preview/app-shell`, and `/playground/*` as starter validation surfaces. They are app-owned and can be removed after setup if links and references are cleaned up too.
|
|
21
|
+
- Keep identity/contact in `config/brand.ts`, and keep all color/theme tokens in `app/globals.css`.
|
|
20
22
|
- Check `config/modules.ts` before assuming CRM, Projects, or Admin routes exist.
|
|
21
23
|
- Prefer composing app-level routes and config before forking logic from `@brightweblabs/*` packages.
|
|
22
24
|
- Keep edits local to this app unless the change is intentionally shared across multiple BrightWeb projects.
|
|
@@ -4,17 +4,32 @@
|
|
|
4
4
|
color-scheme: light;
|
|
5
5
|
--font-sans: "IBM Plex Sans", "Segoe UI", sans-serif;
|
|
6
6
|
--font-display: Georgia, "Times New Roman", serif;
|
|
7
|
+
/* Raw brand tokens: customize these first per client. */
|
|
8
|
+
--brand-primary: #266946;
|
|
9
|
+
--brand-primary-rgb: 38, 105, 70;
|
|
10
|
+
--brand-secondary-rgb: 126, 170, 112;
|
|
11
|
+
--brand-highlight-rgb: 189, 140, 89;
|
|
12
|
+
--brand-positive-rgb: 113, 196, 139;
|
|
13
|
+
/* Semantic theme tokens consumed by the UI. */
|
|
7
14
|
--background: #f3efe5;
|
|
8
15
|
--foreground: #18241d;
|
|
9
16
|
--muted-foreground: #5a665c;
|
|
10
17
|
--border: rgba(24, 36, 29, 0.12);
|
|
11
18
|
--panel: rgba(255, 255, 255, 0.82);
|
|
12
19
|
--panel-strong: #ffffff;
|
|
13
|
-
--accent:
|
|
14
|
-
--accent-soft: rgba(
|
|
20
|
+
--accent: var(--brand-primary);
|
|
21
|
+
--accent-soft: rgba(var(--brand-primary-rgb), 0.12);
|
|
15
22
|
--danger: #b43f3f;
|
|
16
23
|
--ink-soft: #eef1e8;
|
|
17
|
-
--ring: rgba(
|
|
24
|
+
--ring: rgba(var(--brand-primary-rgb), 0.28);
|
|
25
|
+
--surface-glow-cool: rgba(var(--brand-secondary-rgb), 0.18);
|
|
26
|
+
--surface-glow-warm: rgba(var(--brand-highlight-rgb), 0.12);
|
|
27
|
+
--accent-glow-strong: rgba(var(--brand-primary-rgb), 0.18);
|
|
28
|
+
--accent-glow-mid: rgba(var(--brand-primary-rgb), 0.14);
|
|
29
|
+
--accent-glow-soft: rgba(var(--brand-primary-rgb), 0.08);
|
|
30
|
+
--positive-glow-strong: rgba(var(--brand-positive-rgb), 0.5);
|
|
31
|
+
--positive-glow-soft: rgba(var(--brand-positive-rgb), 0.14);
|
|
32
|
+
--positive-glow-subtle: rgba(var(--brand-positive-rgb), 0.15);
|
|
18
33
|
|
|
19
34
|
/* Compatibility aliases so both starters expose the same token surface. */
|
|
20
35
|
--bg: var(--background);
|
|
@@ -32,8 +47,8 @@ body {
|
|
|
32
47
|
margin: 0;
|
|
33
48
|
padding: 0;
|
|
34
49
|
background:
|
|
35
|
-
radial-gradient(circle at 15% 10%,
|
|
36
|
-
radial-gradient(circle at 85% 12%,
|
|
50
|
+
radial-gradient(circle at 15% 10%, var(--surface-glow-cool), transparent 22%),
|
|
51
|
+
radial-gradient(circle at 85% 12%, var(--surface-glow-warm), transparent 18%),
|
|
37
52
|
linear-gradient(180deg, #faf8f1 0%, var(--bg) 48%, #e8e0cf 100%);
|
|
38
53
|
color: var(--text);
|
|
39
54
|
font-family: var(--font-sans), sans-serif;
|
|
@@ -97,7 +112,7 @@ input {
|
|
|
97
112
|
overflow: hidden;
|
|
98
113
|
background:
|
|
99
114
|
linear-gradient(180deg, rgba(255, 255, 255, 0.86), rgba(247, 244, 235, 0.84)),
|
|
100
|
-
radial-gradient(circle at top right,
|
|
115
|
+
radial-gradient(circle at top right, var(--accent-glow-strong), transparent 45%);
|
|
101
116
|
}
|
|
102
117
|
|
|
103
118
|
.starter-hero-card::after {
|
|
@@ -107,7 +122,7 @@ input {
|
|
|
107
122
|
width: 150px;
|
|
108
123
|
height: 150px;
|
|
109
124
|
border-radius: 999px;
|
|
110
|
-
background:
|
|
125
|
+
background: var(--accent-glow-soft);
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
.starter-stat-grid {
|
|
@@ -185,7 +200,7 @@ input {
|
|
|
185
200
|
.preview-glass-card {
|
|
186
201
|
background:
|
|
187
202
|
linear-gradient(180deg, rgba(255, 255, 255, 0.84), rgba(246, 244, 236, 0.76)),
|
|
188
|
-
radial-gradient(circle at top right,
|
|
203
|
+
radial-gradient(circle at top right, var(--accent-glow-soft), transparent 45%);
|
|
189
204
|
}
|
|
190
205
|
|
|
191
206
|
.panel h2,
|
|
@@ -308,7 +323,7 @@ input {
|
|
|
308
323
|
border-radius: 28px;
|
|
309
324
|
background:
|
|
310
325
|
linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(241, 237, 226, 0.84)),
|
|
311
|
-
radial-gradient(circle at top,
|
|
326
|
+
radial-gradient(circle at top, var(--accent-soft), transparent 34%);
|
|
312
327
|
backdrop-filter: blur(16px);
|
|
313
328
|
box-shadow: 0 22px 60px rgba(24, 36, 29, 0.1);
|
|
314
329
|
}
|
|
@@ -328,7 +343,7 @@ input {
|
|
|
328
343
|
border-radius: 28px;
|
|
329
344
|
background:
|
|
330
345
|
linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(246, 243, 235, 0.86)),
|
|
331
|
-
radial-gradient(circle at right top,
|
|
346
|
+
radial-gradient(circle at right top, var(--accent-glow-mid), transparent 35%);
|
|
332
347
|
backdrop-filter: blur(16px);
|
|
333
348
|
}
|
|
334
349
|
|
|
@@ -374,7 +389,7 @@ input {
|
|
|
374
389
|
.preview-stage-panel {
|
|
375
390
|
background:
|
|
376
391
|
linear-gradient(180deg, rgba(23, 37, 29, 0.96), rgba(18, 30, 24, 0.95)),
|
|
377
|
-
radial-gradient(circle at top left,
|
|
392
|
+
radial-gradient(circle at top left, var(--positive-glow-subtle), transparent 34%);
|
|
378
393
|
color: #f4f1e8;
|
|
379
394
|
border-color: rgba(255, 255, 255, 0.1);
|
|
380
395
|
}
|
|
@@ -409,8 +424,8 @@ input {
|
|
|
409
424
|
|
|
410
425
|
.nav-chip.active,
|
|
411
426
|
.nav-chip:hover {
|
|
412
|
-
border-color:
|
|
413
|
-
background:
|
|
427
|
+
border-color: var(--positive-glow-strong);
|
|
428
|
+
background: var(--positive-glow-soft);
|
|
414
429
|
}
|
|
415
430
|
|
|
416
431
|
.preview-surface-grid {
|
|
@@ -510,7 +525,7 @@ input {
|
|
|
510
525
|
}
|
|
511
526
|
|
|
512
527
|
.status.ok {
|
|
513
|
-
background: rgba(
|
|
528
|
+
background: rgba(var(--brand-primary-rgb), 0.14);
|
|
514
529
|
color: var(--accent);
|
|
515
530
|
}
|
|
516
531
|
|
|
@@ -113,6 +113,7 @@ export default function HomePage() {
|
|
|
113
113
|
<h2>Starter controls</h2>
|
|
114
114
|
<ul className="list">
|
|
115
115
|
<li>`config/brand.ts` for client identity and contact details.</li>
|
|
116
|
+
<li>`app/globals.css` for color and theme token management.</li>
|
|
116
117
|
<li>`config/modules.ts` for enabled platform modules.</li>
|
|
117
118
|
<li>`config/env.ts` for infra requirements and readiness checks.</li>
|
|
118
119
|
<li>`.env.local` for per-client service credentials and local runtime overrides.</li>
|
|
@@ -5,7 +5,6 @@ export type StarterBrandConfig = {
|
|
|
5
5
|
tagline: string;
|
|
6
6
|
contactEmail: string;
|
|
7
7
|
supportEmail: string;
|
|
8
|
-
primaryHex: string;
|
|
9
8
|
};
|
|
10
9
|
|
|
11
10
|
export const starterBrandConfig: StarterBrandConfig = {
|
|
@@ -15,5 +14,4 @@ export const starterBrandConfig: StarterBrandConfig = {
|
|
|
15
14
|
tagline: "A configurable Brightweb starter app for shipping new client instances without rebuilding the platform.",
|
|
16
15
|
contactEmail: "hello@example.com",
|
|
17
16
|
supportEmail: "support@example.com",
|
|
18
|
-
primaryHex: "#1f7a45",
|
|
19
17
|
};
|
|
@@ -23,7 +23,7 @@ export const starterModuleConfig: StarterModuleConfig[] = [
|
|
|
23
23
|
{
|
|
24
24
|
key: "crm",
|
|
25
25
|
label: "CRM",
|
|
26
|
-
description: "Contacts
|
|
26
|
+
description: "Contacts and CRM server/data layer, with marketing-adjacent operational data stored in Supabase.",
|
|
27
27
|
enabled: true,
|
|
28
28
|
packageName: "@brightweblabs/module-crm",
|
|
29
29
|
playgroundHref: "/playground/crm",
|
|
@@ -20,11 +20,12 @@ This app is a normal Next.js App Router project with BrightWeb runtime wiring la
|
|
|
20
20
|
- `docs/ai/examples.md`: common setup and customization workflows.
|
|
21
21
|
- `README.md`: first-run setup steps.
|
|
22
22
|
- `components/`: local app component layer for starter surfaces and future product UI.
|
|
23
|
-
- `config/brand.ts`: client
|
|
23
|
+
- `config/brand.ts`: client identity, product naming, and contact inboxes.
|
|
24
24
|
- `config/modules.ts`: module metadata and enablement flags for CRM, Projects, and Admin.
|
|
25
25
|
- `config/client.ts`: aggregated state consumed by starter pages.
|
|
26
26
|
- `config/bootstrap.ts`: bootstrap checklist content for `/bootstrap`.
|
|
27
27
|
- `config/shell.ts`: app-shell registration and navigation wiring.
|
|
28
|
+
- `app/globals.css`: color tokens (raw brand + semantic mappings), typography, and global surface styling.
|
|
28
29
|
- `app/page.tsx`: starter landing page for the generated app.
|
|
29
30
|
- `app/bootstrap/page.tsx`: setup checklist surface.
|
|
30
31
|
- `app/preview/app-shell/page.tsx`: shell preview validation route.
|
|
@@ -34,6 +35,7 @@ This app is a normal Next.js App Router project with BrightWeb runtime wiring la
|
|
|
34
35
|
## Editing strategy
|
|
35
36
|
|
|
36
37
|
- Change client identity first in `config/brand.ts`.
|
|
38
|
+
- Change colors and theme tokens in `app/globals.css`.
|
|
37
39
|
- Check module presence in `config/modules.ts` before editing or creating module-specific routes.
|
|
38
40
|
- Add app-specific UI in `components/` before forking shared package code.
|
|
39
41
|
- Use `config/shell.ts` when navigation or toolbar behavior needs to change.
|
|
@@ -8,6 +8,7 @@ Goal: get the generated starter running with real credentials.
|
|
|
8
8
|
|
|
9
9
|
- Review `.env.local` and replace placeholder values.
|
|
10
10
|
- Review `config/brand.ts` and confirm client identity.
|
|
11
|
+
- Review `app/globals.css` and confirm brand tokens map to the intended visual system.
|
|
11
12
|
- Review `config/modules.ts` before touching module routes.
|
|
12
13
|
- Run the local dev server for this app or workspace.
|
|
13
14
|
- Validate `/`, `/bootstrap`, `/preview/app-shell`, and `/playground/auth`.
|
|
@@ -18,6 +19,7 @@ Goal: get the generated starter running with real credentials.
|
|
|
18
19
|
Goal: update the starter to the real client name and support details.
|
|
19
20
|
|
|
20
21
|
- Edit `config/brand.ts`.
|
|
22
|
+
- Edit `app/globals.css` when palette or theme token mapping needs to change.
|
|
21
23
|
- Move route-specific presentation into `components/` when the home or preview surfaces need app-owned UI.
|
|
22
24
|
- Check `config/client.ts` or `config/bootstrap.ts` if starter copy still references old defaults.
|
|
23
25
|
- Validate the home page and `/preview/app-shell` after the change.
|
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
- `organization_invitations`
|
|
12
12
|
- CRM/org helper functions like `is_org_admin()` and `set_crm_status(...)`
|
|
13
13
|
- CRM/org RLS and triggers
|
|
14
|
+
- app-owned operational contact records, not external ESP topic identifiers
|
|
14
15
|
|
|
15
16
|
## Shared boundary
|
|
16
17
|
|
|
17
18
|
Some marketing data is adjacent to CRM, but the Brightweb v1 split is:
|
|
18
19
|
|
|
19
20
|
- CRM owns operational contact and organization management
|
|
21
|
+
- CRM does not currently define newsletter/product-update subscription tables or Resend Topic mappings
|
|
20
22
|
- Marketing automation remains its own future module boundary
|
|
21
23
|
|
|
22
24
|
## Dependency
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- portal_read_indexes
|
|
2
|
+
-- target: crm
|
|
3
|
+
-- created_at: 2026-04-21T20:15:23.686Z
|
|
4
|
+
|
|
5
|
+
CREATE INDEX IF NOT EXISTS idx_crm_contacts_updated_at_desc
|
|
6
|
+
ON public.crm_contacts (updated_at DESC);
|
|
7
|
+
|
|
8
|
+
CREATE INDEX IF NOT EXISTS idx_crm_contacts_created_at_desc
|
|
9
|
+
ON public.crm_contacts (created_at DESC);
|
|
10
|
+
|
|
11
|
+
CREATE INDEX IF NOT EXISTS idx_crm_contacts_status
|
|
12
|
+
ON public.crm_contacts (status);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_crm_contacts_source
|
|
15
|
+
ON public.crm_contacts (source)
|
|
16
|
+
WHERE source IS NOT NULL;
|
|
17
|
+
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_crm_status_log_changed_at_desc
|
|
19
|
+
ON public.crm_status_log (changed_at DESC);
|
|
20
|
+
|
|
21
|
+
CREATE INDEX IF NOT EXISTS idx_organizations_created_at_desc
|
|
22
|
+
ON public.organizations (created_at DESC);
|