Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ updates:
interval: "weekly"

- package-ecosystem: "pub"
directory: "/packages/formbricks_flutter"
directory: "/packages/formbricks"
schedule:
interval: "weekly"

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ build/
# contains an app → reproducible builds, paired with the fvm-pinned SDK).
# Members don't generate their own lockfile under a workspace, but ignore any
# stray ones just in case.
/packages/formbricks_flutter/pubspec.lock
/packages/formbricks/pubspec.lock
/apps/playground/pubspec.lock

# Melos
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DEFAULT_GOAL := help

SDK_DIR := packages/formbricks_flutter
SDK_DIR := packages/formbricks
PLAYGROUND_DIR := apps/playground
TEST_RESULTS_DIR := test-results
PLATFORMS := ios android
Expand Down Expand Up @@ -97,7 +97,7 @@ test:

test-sdk-machine:
mkdir -p $(TEST_RESULTS_DIR)
cd $(SDK_DIR) && $(FLUTTER) test --machine > ../../$(TEST_RESULTS_DIR)/formbricks_flutter.json
cd $(SDK_DIR) && $(FLUTTER) test --machine > ../../$(TEST_RESULTS_DIR)/formbricks.json

test-playground:
cd $(PLAYGROUND_DIR) && $(FLUTTER) test
Expand Down
65 changes: 25 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Formbricks Flutter

Monorepo for the first-party **Flutter SDK** for [Formbricks](https://formbricks.com)
and its demo app. The SDK mirrors the [React Native SDK](https://github.com/formbricks/react-native):
initialize a workspace, identify users, track actions, and render targeted in-app
surveys inside a WebView backed by `{appUrl}/js/surveys.umd.cjs`.
and its demo app. Initialize a workspace, identify users, track actions, and
render targeted in-app surveys inside a WebView backed by
`{appUrl}/js/surveys.umd.cjs`.

> **Status:** repository skeleton. The SDK currently exposes only a placeholder
> `welcome()`. The public API, survey rendering, CI, and pub.dev publishing land
> in follow-up work — see [Roadmap](#roadmap).
SDK usage docs live in
[`packages/formbricks/README.md`](packages/formbricks/README.md).

## Quick Start

Expand Down Expand Up @@ -73,10 +72,11 @@ The Makefile delegates to `tool/run.sh`, boots a simulator/emulator when it can,
then runs `apps/playground`. Once the app is running, press `r` for hot reload,
`R` for hot restart, and `q` to quit.

You should see a **"Welcome to Formbricks"** header and six SDK-test buttons
(track / setUserId / setAttributes ×2 / setLanguage / logout). They are inert
stubs — each shows a "not wired to the SDK yet" snackbar — until the SDK API
lands in follow-up work.
You should see a **"Welcome to Formbricks"** header, a connection form
(App URL + Workspace ID), a "Trigger Code Action" button, the identity buttons
(setUserId / setAttributes / setAttribute / setLanguage / logout), and
local-storage inspect/clear buttons. Connect to a real workspace to exercise
them end to end.

## Repository layout

Expand All @@ -88,32 +88,31 @@ flutter/
├── sonar-project.properties # SonarCloud config (finalised in a follow-up)
├── LICENSE # MIT
├── packages/
│ └── formbricks_flutter/ # the SDK package (the thing we publish)
│ └── formbricks/ # the SDK package (the thing we publish)
│ ├── lib/
│ │ ├── formbricks_flutter.dart # public exports
│ │ └── src/ # (added in implementation tickets)
│ │ ├── formbricks.dart # public exports
│ │ └── src/ # private implementation
│ ├── test/ # one test file per source file
│ ├── pubspec.yaml
│ ├── CHANGELOG.md
│ ├── LICENSE
│ └── README.md
└── apps/
└── playground/ # demo / manual-QA app (equivalent of RN's apps/playground)
└── playground/ # demo / manual-QA app
├── lib/main.dart # SDK test buttons: track, setUserId, setAttributes, …
├── android/ ios/ # platform projects (iOS + Android only for v1)
├── android/ ios/ # platform projects (iOS + Android only)
├── test/
└── pubspec.yaml
```

This mirrors the RN repo's `packages/*` + `apps/*` split, so anyone moving
between the two SDKs finds the same shape.
A standard `packages/*` + `apps/*` monorepo split.

### Why these locations

| Path | Holds | Rationale |
| ----------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `packages/formbricks_flutter` | The publishable SDK | Single source of the pub.dev package. `src/` is private; only `lib/formbricks_flutter.dart` re-exports the public API. |
| `apps/playground` | Demo app | Real Flutter app on iOS + Android for manual QA of WebView / keyboard / modal behaviour. Excluded from SonarCloud + pub scoring. The RN SDK proved this app is what catches keyboard/touch regressions before customers do, so it ships from day one. |
| Path | Holds | Rationale |
| --------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `packages/formbricks` | The publishable SDK | Single source of the pub.dev package. `src/` is private; only `lib/formbricks.dart` re-exports the public API. |
| `apps/playground` | Demo app | Real Flutter app on iOS + Android for manual QA of WebView / keyboard / modal behaviour. Excluded from SonarCloud + pub scoring. A real demo app is what catches keyboard/touch regressions before customers do, so it ships from day one. |

## Monorepo tooling

Expand Down Expand Up @@ -172,26 +171,26 @@ make pub-publish-dry-run

## Conventions

These are locked in for all follow-up work (full rationale in the RN repo's
`FLUTTER_SDK_PLAN.md`):
Conventions locked in across the SDK:

- **Naming.** Internal types are `FormbricksConfig`, `Logger`, etc. — no
redundant `Flutter` prefix inside a Flutter package. Storage key is
`formbricks-flutter` (distinct from RN's `formbricks-react-native`).
`formbricks-flutter`, namespaced so multiple Formbricks SDKs on one device
never collide.
- **Static public API, hidden singleton.** `Formbricks.track(...)` /
`Formbricks.setup(...)` are static facades over a private singleton — **not**
`Formbricks.instance.track(...)`. The host widget and static API share the
one `Formbricks` class.
- **No `environmentId`.** The SDK accepts `workspaceId` only — no legacy alias
to ever deprecate (RN still carries that debt).
to ever deprecate.
- **Dates cross one boundary.** `DateTime` in memory, ISO-8601 `String` on the
wire and on disk; convert only in `fromJson` / `toJson`. No stray
`DateTime.parse` elsewhere.
- **Testing is mandatory.** Every source file gets a dedicated test file (happy
path + errors + edge cases). PRs aren't mergeable without it; aim for ≥ 80 %
coverage on touched files. Unit tests use `flutter_test` + `mocktail` /
`http`'s `MockClient` — no real network.
- **Targets.** iOS + Android only for v1. A `kIsWeb` guard throws on Flutter Web.
- **Targets.** iOS + Android only; Flutter Web and desktop are not supported.

## Toolchain details

Expand Down Expand Up @@ -260,17 +259,3 @@ fvm flutter run -d emulator # Android, if the emulator id contains "emulato

First Android build is slow because Gradle downloads the NDK and CMake
(approximately 3 GB, one-time). Subsequent builds reuse them.

## Roadmap

| Stage | Scope |
| ------------------------ | ----------------------------------------------------------------- |
| Repo + monorepo skeleton | This ✅ |
| `setup` + command queue | `setup` function, `CommandQueue`, `FormbricksConfig`, `ApiClient` |
| Track + show survey | `track` + survey rendering (WebView) |
| CI | GitHub Actions (format / analyze / test / build) |
| Code quality | SonarCloud wiring + quality gate |

The canonical spec and the React-Native→Flutter architecture mapping live in
[`docs/FLUTTER_SDK_PLAN.md`](docs/FLUTTER_SDK_PLAN.md). The reference RN source is
the `formbricks/react-native` repo.
10 changes: 5 additions & 5 deletions apps/playground/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Playground

Demo / manual-QA app for the [`formbricks_flutter`](../../packages/formbricks_flutter)
Demo / manual-QA app for the [`formbricks`](../../packages/formbricks)
SDK. Targets iOS + Android.

It calls `Formbricks.setup` on launch (reading `APP_URL` / `WORKSPACE_ID` from
`--dart-define`, mirroring the React Native playground's env vars) and shows the
setup status. The six SDK-test buttons (track / setUserId / setAttributes ×2 /
setLanguage / logout) are inert stubs until the rest of the API lands; each shows
a "not wired to the SDK yet" snackbar.
`--dart-define`) and shows the connection status. Once connected, use the
"Trigger Code Action" button and the identity buttons (setUserId / setAttributes
/ setAttribute / setLanguage / logout) to drive the SDK against a real workspace;
the local-storage buttons inspect and clear the persisted config.

## Run

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:formbricks_flutter/formbricks_flutter.dart';
import 'package:formbricks/formbricks.dart';
import 'package:formbricks_playground/main.dart';
import 'package:integration_test/integration_test.dart';

Expand Down
2 changes: 1 addition & 1 deletion apps/playground/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:formbricks_flutter/formbricks_flutter.dart';
import 'package:formbricks/formbricks.dart';

const String _defaultAppUrl = String.fromEnvironment('APP_URL');
const String _defaultWorkspaceId = String.fromEnvironment('WORKSPACE_ID');
Expand Down
6 changes: 3 additions & 3 deletions apps/playground/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: formbricks_playground
description: "Demo / manual-QA app for the formbricks_flutter SDK."
description: "Demo / manual-QA app for the formbricks SDK."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
Expand Down Expand Up @@ -39,8 +39,8 @@ dependencies:
cupertino_icons: ^1.0.8

# The local SDK package, resolved through the pub workspace.
formbricks_flutter:
path: ../../packages/formbricks_flutter
formbricks:
path: ../../packages/formbricks

dev_dependencies:
flutter_test:
Expand Down
Loading
Loading