Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ─── Copy to .env for local dev. NEVER commit real values. ───────────────────────
NODE_ENV=development
PORT=3000
HOST=127.0.0.1
# web | worker | all
APP_ROLE=all

# Postgres (Azure: use Entra auth via managed identity, see docs/deploy.md)
DATABASE_URL=postgres://dashflow:dashflow@localhost:5432/dashflow

# easyauth (Azure Container Apps) | dev (local only, refuses to run in production)
AUTH_MODE=dev
# Dev auth refuses any HOST but localhost unless you set this (containers need 0.0.0.0).
DEV_AUTH_ALLOW_REMOTE=false
DEV_USER_EMAIL=dev.user@contoso.onmicrosoft.com
DEV_USER_OID=00000000-0000-0000-0000-000000000001
DEV_USER_TID=00000000-0000-0000-0000-000000000002

# Comma-separated home tenant IDs allowed to sign in (empty = any tenant EasyAuth lets through)
ALLOWED_TENANT_IDS=
# Verify X-MS-TOKEN-AAD-ID-TOKEN signature against Entra JWKS (requires token store)
EASYAUTH_VALIDATE_TOKEN=false
EASYAUTH_CLIENT_ID=
# Comma-separated Entra object IDs that become Owner without the setup code
BOOTSTRAP_OWNER_OIDS=

# 32-byte base64 key for encrypting secrets stored in Postgres: `openssl rand -base64 32`
APP_ENCRYPTION_KEY=
# Optional: Key Vault used for secret references (https://<name>.vault.azure.net)
KEY_VAULT_URI=
# Client ID of the user-assigned managed identity (Azure only)
AZURE_CLIENT_ID=

# Public base URL, used for OAuth redirect (Partner Center consent)
PUBLIC_BASE_URL=http://localhost:3000

# Load synthetic data and allow demo tenants
DEMO_MODE=true
LOG_LEVEL=info
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Bug report
about: Something is broken
labels: bug
---

**What happened**

**What you expected**

**How to reproduce**

**Environment**
- Deployment: Container Apps / Docker / other
- Connection type: Azure / Lighthouse / Partner Center / Nerdio / demo
- Image tag or commit:

**Logs**

<!-- Paste only what is needed, and redact tenant IDs, subscription IDs, domains and user names. -->
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
blank_issues_enabled: true
contact_links:
- name: Try the live demo
url: https://bg-red.github.io/dashflow/
about: See what DashFlow does before installing it
- name: Security issue
url: https://github.com/BG-Red/dashflow/security/advisories/new
about: Report a vulnerability privately, not as a public issue
- name: Question or setup help
url: https://github.com/BG-Red/dashflow/blob/main/SUPPORT.md
about: Connection diagnostics, permissions and troubleshooting
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Something DashFlow should do
labels: enhancement
---

**What do you need to know or do?**
<!-- The operational question, not the implementation. "Which customers had a bad week" is more
useful than "add a table widget". -->

**How do you answer it today?**

**Which connection types does this apply to?**
<!-- Azure direct / Lighthouse / Partner Center / Nerdio / any -->

**Anything else**
<!-- Screenshots welcome. Please redact tenant identifiers and user names. -->
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule: { interval: weekly }
open-pull-requests-limit: 5
groups:
dev-tooling:
patterns: ["@biomejs/*", "typescript", "vite", "@vitejs/*", "lefthook", "drizzle-kit"]
react:
patterns: ["react", "react-dom", "@types/react", "@types/react-dom"]
- package-ecosystem: github-actions
directory: "/"
schedule: { interval: weekly }
- package-ecosystem: docker
directory: "/"
schedule: { interval: weekly }
18 changes: 18 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## What this changes

<!-- One or two sentences. The why matters more than the what. -->

## How it was verified

<!-- Which of these did you run? Anything you could not check, say so plainly. -->

- [ ] `bun test` (with `TEST_DATABASE_URL` for the SQL and parity suites)
- [ ] `bunx playwright test`
- [ ] `bun run lint && bun run typecheck`
- [ ] Clicked through the change in the running app

## Checklist

- [ ] No tenant IDs, subscription IDs, real domains or user names anywhere in the diff
- [ ] New metrics are in the catalog, not ad-hoc SQL
- [ ] Docs updated if behaviour or configuration changed
96 changes: 96 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: dashflow
POSTGRES_PASSWORD: dashflow
POSTGRES_DB: dashflow_test
ports: ["5432:5432"]
options: >-
--health-cmd "pg_isready -U dashflow"
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install --frozen-lockfile
- name: Lint
run: bun run lint
- name: Typecheck (server and packages)
run: bun run typecheck
- name: Typecheck (web)
run: bunx tsc --noEmit -p apps/web/tsconfig.json
- name: Test
run: bun run test
env:
TEST_DATABASE_URL: postgres://dashflow:dashflow@localhost:5432/dashflow_test
- name: Build web
run: bun run build

e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install --frozen-lockfile
- name: Install the browser
run: bunx playwright install --with-deps chromium
- name: End-to-end (demo build, no database)
run: bunx playwright test
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report
retention-days: 7

secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Scan history for secrets and tenant identifiers
uses: gitleaks/gitleaks-action@v2
env:
GITLEAKS_CONFIG: .gitleaks.toml
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build the container image
uses: docker/build-push-action@v6
with:
context: .
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
tags: dashflow:ci

bicep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate the deployment template
run: az bicep build --file infra/main.bicep --stdout > /dev/null
45 changes: 45 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Demo

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14
- run: bun install --frozen-lockfile
- name: Build the demo bundle
# The demo runs entirely in the browser: the same UI, a synthetic estate, no server.
run: bun run build:demo
env:
DEMO_BASE: /dashflow/
- name: Single-page fallback for deep links
run: cp apps/web/dist-demo/index.html apps/web/dist-demo/404.html
- uses: actions/upload-pages-artifact@v3
with:
path: apps/web/dist-demo

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- id: deploy
uses: actions/deploy-pages@v4
50 changes: 50 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Release

on:
push:
tags: ["v*"]
workflow_dispatch:

permissions:
contents: read
packages: write
id-token: write
attestations: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
# Pinned rather than ${{ github.repository }}: GHCR lowercases image names, so a
# repository with capitals would publish to a path the docs do not mention.
images: ghcr.io/bg-red/dashflow
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- id: build
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
sbom: true
provenance: mode=max
- name: Attest the build
uses: actions/attest-build-provenance@v2
with:
subject-name: ghcr.io/bg-red/dashflow
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# deps / build
node_modules/
dist/
dist-demo/
*.tsbuildinfo
coverage/
playwright-report/
test-results/

# secrets — never commit these
.env
.env.*
!.env.example
*.pem
*.pfx
*.key
*.crt
*.p12
secrets/
.azure/
infra/*.parameters.local.json
infra/**/*.local.bicepparam

# data dumps / exports that could contain tenant data
*.dump
*.sql.gz
exports/
fixtures/raw/
.pgdata/

# OS / editor
.DS_Store
.idea/
.vscode/*
!.vscode/extensions.json
Loading
Loading