Compare commits

..

No commits in common. "22f50d64f9900ac18c753ca73c264a1c8f4f6ed8" and "4fc89c4d3f8aa04dabfec691b73429427f6beae5" have entirely different histories.

6 changed files with 32 additions and 138 deletions

View file

@ -32,8 +32,7 @@ This MVP uses Drizzle with Bun SQLite for local file-backed persistence.
- `bun run test`: run the unit test stage in all workspaces. - `bun run test`: run the unit test stage in all workspaces.
- `bun run test:unit`: run Vitest explicitly as the unit test stage. - `bun run test:unit`: run Vitest explicitly as the unit test stage.
- `bun run test:e2e`: build and run Playwright browser smoke and QA checks. - `bun run test:e2e`: build and run Playwright browser smoke and QA checks.
- `bun run test:qa`: run the release gate through Turbo across check, unit, - `bun run test:qa`: run the release gate through Turbo.
build, Storybook, and e2e tasks.
- `bun run build`: build the UI package, production website, and Bun server. - `bun run build`: build the UI package, production website, and Bun server.
- `bun run preview`: preview the production web build. - `bun run preview`: preview the production web build.
- `bun run storybook`: start the UI package component explorer on port 6006. - `bun run storybook`: start the UI package component explorer on port 6006.
@ -103,9 +102,7 @@ bun run test:qa
The gate runs TypeScript checks, Vitest coverage for model, The gate runs TypeScript checks, Vitest coverage for model,
persistence, renderer, datasource mocks, and presentation boundaries, the persistence, renderer, datasource mocks, and presentation boundaries, the
production build, the static Storybook build, and Playwright desktop/mobile production build, the static Storybook build, and Playwright desktop/mobile
smoke checks against the built adapter output. Turbo owns the release task smoke checks against the built adapter output. Playwright also performs
graph; app package scripts stay as leaf commands and do not re-run the QA
pipeline internally. Playwright also performs
baseline screenshot checks, keyboard navigation checks, reduced-motion checks, baseline screenshot checks, keyboard navigation checks, reduced-motion checks,
landmark checks, and axe accessibility checks against the real model-driven landmark checks, and axe accessibility checks against the real model-driven
route. route.

View file

@ -11,6 +11,7 @@
"test": "vitest run", "test": "vitest run",
"test:unit": "vitest run", "test:unit": "vitest run",
"test:e2e": "env -u NO_COLOR playwright test", "test:e2e": "env -u NO_COLOR playwright test",
"test:qa": "bun run check && bun run test:unit && bun run build && bun run test:e2e",
"db:generate": "drizzle-kit generate", "db:generate": "drizzle-kit generate",
"db:check": "drizzle-kit check" "db:check": "drizzle-kit check"
}, },

View file

@ -21,13 +21,13 @@ export default defineConfig({
}, },
webServer: [ webServer: [
{ {
command: `DISABLE_LIVE_DATASOURCES=1 DATABASE_URL=${databaseUrl} HOST=127.0.0.1 PORT=${port} bun build/index.js`, command: `DISABLE_LIVE_DATASOURCES=1 bun run build && DISABLE_LIVE_DATASOURCES=1 DATABASE_URL=${databaseUrl} HOST=127.0.0.1 PORT=${port} bun build/index.js`,
url: baseURL, url: baseURL,
reuseExistingServer: false, reuseExistingServer: false,
timeout: 120_000, timeout: 120_000,
}, },
{ {
command: `cd ../.. && STORYBOOK_STATIC_PORT=${storybookPort} bun apps/web/tests/e2e/storybook-server.ts`, command: `cd ../.. && bun run build-storybook && STORYBOOK_STATIC_PORT=${storybookPort} bun apps/web/tests/e2e/storybook-server.ts`,
url: storybookURL, url: storybookURL,
reuseExistingServer: false, reuseExistingServer: false,
timeout: 120_000, timeout: 120_000,

View file

@ -18,62 +18,10 @@ describe("workspace boundaries", () => {
expect(packageJson.private).toBe(true); expect(packageJson.private).toBe(true);
expect(packageJson.workspaces).toEqual(["apps/*", "packages/*"]); expect(packageJson.workspaces).toEqual(["apps/*", "packages/*"]);
expect(packageJson.scripts?.build).toBe("turbo run build"); expect(packageJson.scripts?.build).toBe("turbo build");
expect(existsSync(join(root, "turbo.json"))).toBe(true); expect(existsSync(join(root, "turbo.json"))).toBe(true);
}); });
test("keeps release orchestration in the root turbo task graph", () => {
const rootPackage = JSON.parse(
readFileSync(join(root, "package.json"), "utf8"),
) as {
scripts?: Record<string, string>;
};
const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"),
) as { scripts?: Record<string, string> };
const turboConfig = JSON.parse(
readFileSync(join(root, "turbo.json"), "utf8"),
) as {
globalDependencies?: string[];
tasks?: Record<string, { env?: string[] }>;
};
expect(rootPackage.scripts?.["test:qa"]).toBe(
"turbo run check test:unit build @dimensionlab/ui#build-storybook @dimensionlab/web#test:e2e",
);
expect(webPackage.scripts).not.toHaveProperty("test:qa");
expect(turboConfig.tasks).not.toHaveProperty("test:qa");
expect(turboConfig.globalDependencies).toEqual(
expect.arrayContaining(["bun.lock", "tsconfig.base.json"]),
);
expect(turboConfig.tasks?.["test:e2e"]?.env).toEqual(
expect.arrayContaining([
"CI",
"PLAYWRIGHT_DATABASE_URL",
"PLAYWRIGHT_PORT",
"PLAYWRIGHT_STORYBOOK_PORT",
]),
);
});
test("lets turbo build app and Storybook artifacts before e2e serves them", () => {
const playwrightConfig = readFileSync(
join(root, "apps/web/playwright.config.ts"),
"utf8",
);
const turboConfig = JSON.parse(
readFileSync(join(root, "turbo.json"), "utf8"),
) as {
tasks?: Record<string, { dependsOn?: string[] }>;
};
expect(playwrightConfig).not.toContain("bun run build &&");
expect(playwrightConfig).not.toContain("bun run build-storybook");
expect(turboConfig.tasks?.["test:e2e"]?.dependsOn).toEqual(
expect.arrayContaining(["@dimensionlab/ui#build-storybook"]),
);
});
test("keeps the website app and reusable UI library as separate packages", () => { test("keeps the website app and reusable UI library as separate packages", () => {
const webPackage = JSON.parse( const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"), readFileSync(join(root, "apps/web/package.json"), "utf8"),

View file

@ -9,18 +9,18 @@
"packages/*" "packages/*"
], ],
"scripts": { "scripts": {
"dev": "turbo run dev --filter=@dimensionlab/web", "dev": "turbo dev --filter=@dimensionlab/web",
"build": "turbo run build", "build": "turbo build",
"preview": "turbo run preview --filter=@dimensionlab/web", "preview": "bun run --cwd apps/web preview",
"storybook": "turbo run storybook --filter=@dimensionlab/ui", "storybook": "turbo storybook --filter=@dimensionlab/ui",
"build-storybook": "turbo run build-storybook --filter=@dimensionlab/ui", "build-storybook": "turbo build-storybook --filter=@dimensionlab/ui",
"check": "turbo run check", "check": "turbo check",
"test": "turbo run test:unit", "test": "turbo test:unit",
"test:unit": "turbo run test:unit", "test:unit": "turbo test:unit",
"test:e2e": "turbo run test:e2e --filter=@dimensionlab/web", "test:e2e": "turbo test:e2e --filter=@dimensionlab/web",
"test:qa": "turbo run check test:unit build @dimensionlab/ui#build-storybook @dimensionlab/web#test:e2e", "test:qa": "turbo test:qa",
"db:generate": "turbo run db:generate --filter=@dimensionlab/web", "db:generate": "bun run --cwd apps/web db:generate",
"db:check": "turbo run db:check --filter=@dimensionlab/web" "db:check": "bun run --cwd apps/web db:check"
}, },
"devDependencies": { "devDependencies": {
"turbo": "^2.5.0" "turbo": "^2.5.0"

View file

@ -1,16 +1,9 @@
{ {
"$schema": "https://turbo.build/schema.json", "$schema": "https://turbo.build/schema.json",
"globalDependencies": [
"bun.lock",
"package.json",
"tsconfig.base.json",
"tsconfig.json"
],
"tasks": { "tasks": {
"build": { "build": {
"dependsOn": ["^build"], "dependsOn": ["^build"],
"outputs": ["dist/**", "build/**"], "outputs": ["dist/**", "build/**"]
"env": ["NODE_ENV", "VITE_*"]
}, },
"check": { "check": {
"dependsOn": ["^build"], "dependsOn": ["^build"],
@ -18,78 +11,33 @@
}, },
"test:unit": { "test:unit": {
"dependsOn": ["^build"], "dependsOn": ["^build"],
"outputs": [], "outputs": []
"env": [
"AGENT_CONFIG_TOKEN",
"DASHBOARD_MIGRATIONS_DIR",
"DATABASE_URL",
"DISABLE_LIVE_DATASOURCES",
"PROMETHEUS_BASE_URL"
]
}, },
"build-storybook": { "build-storybook": {
"dependsOn": ["^build"], "dependsOn": ["^build"],
"outputs": ["storybook-static/**"], "outputs": ["storybook-static/**"]
"env": ["NODE_ENV", "STORYBOOK_*", "VITE_*"]
}, },
"test:e2e": { "test:e2e": {
"dependsOn": ["build", "^build"],
"outputs": ["test-results/**", "playwright-report/**"]
},
"test:qa": {
"dependsOn": [ "dependsOn": [
"check",
"test:unit",
"build", "build",
"^build", "build-storybook",
"@dimensionlab/ui#build-storybook" "test:e2e"
], ],
"outputs": ["test-results/**", "playwright-report/**"], "outputs": []
"env": [
"AGENT_CONFIG_TOKEN",
"CI",
"DASHBOARD_MIGRATIONS_DIR",
"DATABASE_URL",
"DISABLE_LIVE_DATASOURCES",
"PLAYWRIGHT_DATABASE_URL",
"PLAYWRIGHT_PORT",
"PLAYWRIGHT_STORYBOOK_PORT",
"PROMETHEUS_BASE_URL",
"STORYBOOK_STATIC_PORT"
]
},
"db:generate": {
"cache": false
},
"db:check": {
"outputs": [],
"env": ["DATABASE_URL"]
}, },
"dev": { "dev": {
"cache": false, "cache": false,
"persistent": true, "persistent": true
"env": [
"AGENT_CONFIG_TOKEN",
"DASHBOARD_DEV_API_HOST",
"DASHBOARD_DEV_API_PORT",
"DASHBOARD_DEV_API_TARGET",
"DASHBOARD_MIGRATIONS_DIR",
"DATABASE_URL",
"HOST",
"PORT",
"PROMETHEUS_BASE_URL"
]
},
"preview": {
"cache": false,
"persistent": true,
"env": [
"AGENT_CONFIG_TOKEN",
"DASHBOARD_MIGRATIONS_DIR",
"DATABASE_URL",
"HOST",
"PORT",
"PROMETHEUS_BASE_URL"
]
}, },
"storybook": { "storybook": {
"cache": false, "cache": false,
"persistent": true, "persistent": true
"env": ["HOST", "PORT", "STORYBOOK_*", "VITE_*"]
} }
} }
} }