Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9e274d2
Initial plan
Copilot Feb 25, 2026
205766e
feat: replace todo app with FlagdSchemaAbstraction port in wasm-tryout
Copilot Feb 25, 2026
744086e
move projects
DanielHabenicht Mar 6, 2026
2d1bd6d
rename and check build
DanielHabenicht Mar 6, 2026
97d8d92
new structure
DanielHabenicht Mar 6, 2026
099edbb
add json schema generation
DanielHabenicht Mar 6, 2026
5214282
remove db
DanielHabenicht Mar 6, 2026
3ad9545
use json schema generator
DanielHabenicht Mar 6, 2026
2eae5b7
remove schema
DanielHabenicht Mar 6, 2026
f678340
fix import/export and add tests
DanielHabenicht Mar 6, 2026
2a1d5fa
connect wasm and api to frontend (just generation)
DanielHabenicht Mar 6, 2026
a7b9ac8
add entities
DanielHabenicht Mar 7, 2026
b8e5900
rename collection
DanielHabenicht Mar 7, 2026
d35cb7f
add new flag store
DanielHabenicht Mar 7, 2026
f17da0e
add wasm backend
DanielHabenicht Mar 8, 2026
842af66
wip
DanielHabenicht Mar 9, 2026
ca675f0
format
DanielHabenicht Mar 9, 2026
d89a00c
remove unecessary files
DanielHabenicht Apr 15, 2026
bf303e8
fix build errors
DanielHabenicht Apr 15, 2026
4ef1aef
working
DanielHabenicht Apr 15, 2026
1d29fbc
refactoring
DanielHabenicht Apr 15, 2026
c40cea7
scalar
DanielHabenicht Apr 15, 2026
257d516
added wasm and rest backend
DanielHabenicht Apr 15, 2026
c424760
better working
DanielHabenicht Apr 15, 2026
8387a6b
update
DanielHabenicht Apr 15, 2026
d555b2f
devcontainer
DanielHabenicht Apr 16, 2026
aa11e02
fix schema import actions
DanielHabenicht Apr 20, 2026
9d046fd
readd import functionality
DanielHabenicht Apr 20, 2026
44af84e
use guids
DanielHabenicht Apr 20, 2026
f11453f
fix build errors
DanielHabenicht Apr 20, 2026
ec40322
move debug buttons
DanielHabenicht Apr 22, 2026
f056d0d
fix duplicate flags
DanielHabenicht Apr 22, 2026
910b0ab
wip
DanielHabenicht Apr 22, 2026
2cb3abf
ci/docker: build and serve the .NET stack, drop Rust
DanielHabenicht Jul 12, 2026
1ccaabc
fix: complete flags-file flow so e2e suite passes
DanielHabenicht Jul 12, 2026
1bbbbcc
refactor: refresh playground schema reactively; clarify SQLite
DanielHabenicht Jul 12, 2026
4c1fefc
feat: blended runtime backends (in-browser wasm + REST remotes)
DanielHabenicht Jul 12, 2026
5c1dcbe
feat: clickable breadcrumbs; rename source crumb to "Overview"
DanielHabenicht Jul 12, 2026
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
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"ms-playwright.playwright",
"vitest.explorer",
"dbaeumer.vscode-eslint",
"tamasfe.even-better-toml"
"ms-dotnettools.csdevkit",
"Angular.ng-template",
"ms-vscode-remote.remote-containers"
],
"settings": {}
}
Expand Down
9 changes: 8 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ ui/dist
ui/coverage
ui/test-results
ui/playwright-report
**/*.log
ui/public
**/*.log

# Generated / local build artifacts (produced inside the image instead)
**/bin
**/obj
ui/OpenFeatureManager.Api.json
ui/src/app/api-client
29 changes: 1 addition & 28 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Rust Backend Checks
name: Checks

on:
pull_request:
Expand All @@ -10,33 +10,6 @@ on:
workflow_dispatch:

jobs:
rust-backend:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.93.0
components: rustfmt

- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2

- name: Check formatting
run: cargo fmt --all --check

- name: Validate backend builds
run: cargo check --all-targets

- name: Run backend tests
run: cargo test --all-targets

prettier:
runs-on: ubuntu-latest
permissions:
Expand Down
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ Cargo.lock
.env
.env.local

bin
obj

public/*
!public/.gitkeep

flags/*
!flags/demo.flagd.json

ui/openapi.json
ui/OpenFeatureManager.Api.json

# Zensical build output
site/
Expand All @@ -35,3 +38,8 @@ services/azurite/azurite-store/
services/azurite/azurite-logs/
services/azurite/certs/*
!services/azurite/certs/.gitkeep

# sqlite
*.db
*.db-shm
*.db-wal
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"chat.tools.terminal.autoApprove": {
"dotnet build": true,
"dotnet publish": true
}
}
53 changes: 0 additions & 53 deletions Cargo.toml

This file was deleted.

94 changes: 61 additions & 33 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,79 +1,107 @@
FROM rust:1.93-bookworm AS backend-builder
# ─── Backend build: .NET API (also emits the OpenAPI document to ui/) ─────────
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS backend-builder

WORKDIR /app

# Copy manifests and build script first (these rarely change)
COPY Cargo.toml Cargo.lock* ./
# ── Toolchain (kept before COPY src so source changes don't re-run these) ──
# Bootsharp compiles the WASM project into an npm package at
# src/OpenFeatureManager.Wasm/bin/bootsharp (consumed by the UI via a file:
# dependency). browser-wasm publishing needs the wasm-tools workload; Debug
# skips the heavy NativeAOT-LLVM path — the REST image never runs the wasm, it
# only needs the generated bindings so the frontend compiles.
RUN dotnet workload install wasm-tools

# The browser-wasm native compile needs python (emscripten/emcc); Bootsharp's
# post-build step bundles its JS with `npx rollup`, so node + rollup are needed too.
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 nodejs npm \
&& ln -sf /usr/bin/python3 /usr/bin/python \
&& npm install -g rollup \
&& rm -rf /var/lib/apt/lists/*

# Create dummy source and build directory
RUN mkdir -p src ui && echo "fn main() {}" > src/main.rs

# Build dependencies (this layer is cached and reused)
RUN cargo build --release
# ui/ must exist so the API's OpenApiGenerateDocumentsOnBuild target can emit
# ui/openapi.json (see OpenFeatureManager.Api.csproj).
RUN mkdir -p ui

# Copy actual source code
COPY build.rs ./
COPY schema ./schema
COPY src ./src
COPY schema ./schema

RUN dotnet publish src/OpenFeatureManager.Wasm/OpenFeatureManager.Wasm.csproj -c Debug

# Build the final release (only user code is recompiled)
RUN cargo build --release
RUN dotnet publish src/OpenFeatureManager.Api/OpenFeatureManager.Api.csproj \
-c Release \
-o /app/publish


# ─── OpenAPI document artifact (consumed by CI docker-image.yml) ──────────────
# The API emits its document as OpenFeatureManager.Api.json (see the csproj and
# scripts/setup-api-client.js); expose it as openapi.json for downstream tooling.
FROM scratch AS artifacts

COPY --from=backend-builder /app/ui/openapi.json /openapi.json
COPY --from=backend-builder /app/ui/OpenFeatureManager.Api.json /openapi.json


FROM openapitools/openapi-generator-cli:v7.19.0 AS api-client-generator
# ─── Generate the typescript-angular API client from the OpenAPI document ─────
FROM openapitools/openapi-generator-cli:v7.21.0 AS api-client-generator

WORKDIR /local

COPY ui/.openapi-generator-ignore /local/.openapi-generator-ignore
COPY --from=backend-builder /app/ui/openapi.json /local/openapi.json
COPY --from=backend-builder /app/ui/OpenFeatureManager.Api.json /local/openapi.json

RUN openapi-generator-cli generate \
-i /local/openapi.json \
-g typescript-angular \
-o /local/api-client


# ─── Frontend build: Angular UI ───────────────────────────────────────────────
FROM node:22-bookworm-slim AS frontend-builder

WORKDIR /ui

# schema/ is resolved as ../../schema by the schema-type generator.
COPY schema /schema

# The bootsharp package is a file: dependency at ../src/.../bin/bootsharp
# relative to ui/; it must exist before npm ci links it into node_modules.
COPY --from=backend-builder /app/src/OpenFeatureManager.Wasm/bin/bootsharp /src/OpenFeatureManager.Wasm/bin/bootsharp

COPY ui/package*.json ./
RUN npm ci --ignore-scripts

COPY ui/ ./
COPY --from=api-client-generator /local/api-client ./src/app/api-client

RUN cp ./.openapi-generator-ignore ./src/app/api-client/.openapi-generator-ignore \
&& npm run ng -- build --configuration production
# REST backend, served same-origin by the API container.
ENV FLAGD_UI_BACKEND_TYPE=rest

# generate:api-client applies the post-generation patches to the client copied
# from the generator stage (the OpenAPI spec is absent here, so it skips the
# generation step itself). generate:schema-types and generate-environments are
# the same scripts npm runs via postinstall/prebuild.
RUN npm run generate:api-client \
&& node scripts/generate-environments.js \
&& npm run generate:schema-types \
&& npm run ng -- build --configuration production

FROM debian:bookworm-slim AS runtime

RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& adduser --system --group --no-create-home appuser
# ─── Runtime: ASP.NET serving the API + built UI on one port ──────────────────
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime

WORKDIR /app

COPY --from=backend-builder /app/target/release/flagd-ui /usr/local/bin/flagd-ui
COPY --from=frontend-builder /public ./public
COPY --from=backend-builder /app/publish ./
COPY --from=frontend-builder /public ./wwwroot
COPY schema ./schema

ENV SERVER_PORT=3000 \
STATIC_DIR=./public \
FLAGS_DIR=./flags \
FLAGD_SCHEMA_FILE=./schema/flagd-schema.json
# SQLite database lives in a world-writable dir so the container can run as an
# arbitrary (docker-compose provided) UID.
RUN mkdir -p /app/data && chmod 777 /app/data

EXPOSE 3000
ENV ASPNETCORE_URLS=http://+:3000 \
ConnectionStrings__Flagd="Data Source=/app/data/flagd.db" \
FlagdSchemaFile=./schema/flagd-schema.json

USER appuser
EXPOSE 3000

ENTRYPOINT ["/usr/local/bin/flagd-ui"]
ENTRYPOINT ["dotnet", "OpenFeatureManager.Api.dll"]
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,24 @@ This project provides a user-friendly web interface for the OpenFeature flagd se
## UI

![flagd-ui editing a flag](https://raw.githubusercontent.com/DanielHabenicht/flagd-ui/main/docs/assets/images/ui-editing-flag.png)

## Development

```bash
cd src
dotnet publish
dotnet run --project OpenFeatureManager.Api
# http://localhost:5000/scalar/

cd ui
npm install
npm start
# http://localhost:4200
```

To build and run the full stack (API + UI) in a single container:

```bash
docker compose up --build
# http://localhost:3000
```
65 changes: 0 additions & 65 deletions build.rs

This file was deleted.

Loading
Loading