Skip to content

feat(amplify_event_enrichment): add example app - #7076

Open
ekjotmultani wants to merge 16 commits into
feat/event-enrichment-clientfrom
feat/event-enrichment-client-example
Open

feat(amplify_event_enrichment): add example app#7076
ekjotmultani wants to merge 16 commits into
feat/event-enrichment-clientfrom
feat/event-enrichment-client-example

Conversation

@ekjotmultani

Copy link
Copy Markdown
Member

Description

Adds the example Flutter app for the amplify_event_enrichment package, demonstrating event enrichment client usage with session tracking, global fields, and lifecycle observation.

This PR is stacked on #7029 (core package implementation). Review #7029 first.

Structure (3-way split)

PR Branch Content
#7029 feat/event-enrichment-client Core package (lib only)
This PR feat/event-enrichment-client-example Example app (92 files)
#7068 feat/event-enrichment-client-tests Unit tests (5 files)

What's included

  • Full Flutter example app with Android, iOS, and macOS targets
  • Demonstrates EventEnrichmentClient initialization and usage
  • Shows session management, global fields, and lifecycle observation

@codecov-commenter

codecov-commenter commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 41.28%. Comparing base (cedd2ed) to head (c25df04).

Additional details and impacted files
@@                       Coverage Diff                        @@
##           feat/event-enrichment-client    #7076      +/-   ##
================================================================
+ Coverage                         40.98%   41.28%   +0.29%     
================================================================
  Files                               121      124       +3     
  Lines                              8273     8333      +60     
  Branches                           3598     3628      +30     
================================================================
+ Hits                               3391     3440      +49     
- Misses                             4882     4893      +11     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

dependencies:
amplify_event_enrichment:
path: ../
amplify_foundation_dart: ">=2.11.0 <2.12.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In example apps for our libs in this repo, I'd use any as a version so that we don't need to care about version bumps.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, switched the example deps to any.

@ekjotmultani
ekjotmultani force-pushed the feat/event-enrichment-client-example branch from 14c3d90 to 2a2ccfe Compare July 6, 2026 20:24
@ekjotmultani
ekjotmultani marked this pull request as ready for review July 6, 2026 22:42
@ekjotmultani
ekjotmultani requested a review from a team as a code owner July 6, 2026 22:42
@ekjotmultani
ekjotmultani force-pushed the feat/event-enrichment-client branch from 90d1c28 to f357a12 Compare July 29, 2026 21:23
@ekjotmultani
ekjotmultani force-pushed the feat/event-enrichment-client-example branch from 2a2ccfe to 9b0c398 Compare July 29, 2026 21:23
@ekjotmultani
ekjotmultani force-pushed the feat/event-enrichment-client-example branch 3 times, most recently from 7fbd9e8 to c5c9e18 Compare August 21, 2026 16:57
Records an event, stops the session, then records again and asserts the second event gets a new session id with no stop_timestamp, proving a stopped session is not reused.
Apply prefer_const, prefer_int_literals, and cascade_invocations fixes plus formatting so the per-package CI passes analyze (--fatal-infos --fatal-warnings) and the format check on both enrichment packages.
…etadata provider

- assert a sink failure surfaces through Result.error rather than throwing
- assert EventEnrichmentClientFlutter.create degrades gracefully when a device metadata provider throws
- add coverage for the default PlatformDeviceMetadataProvider
…'s new surface

Adapts the suites to the async EventSink and Future-returning record().

New coverage:
- a sink that suspends before throwing, proving record() catches an
  asynchronous failure and returns it as Result.error instead of letting it
  escape to the zone. Verified by removing the await, which makes this test
  fail with an unhandled "async sink failure".
- a sink that throws synchronously, kept as a separate case.
- the injected clientIdProvider, its failure fallback, and the shared
  preferences default.
- the wrapper's session controls, including recording with
  autoSessionTracking disabled to pin the lazy session start.
… semantics

Renames the fakes and call sites for `EventSink` -> `Sender` and
`sink:` -> `sender:`.

New coverage for the session-stop fix, all of which fails without it:

- SessionManager: resume after an explicit `stopSession` leaves tracking
  stopped; resume after a timeout stop still starts a fresh session;
  `startSession` clears the explicit stop so lifecycle handling resumes;
  `clearSession` counts as explicit; a stop with no preceding background
  is not resurrected either
- FlutterLifecycleObserver: neither `onResume` nor a `resumed`
  `AppLifecycleState` restarts a session stopped explicitly
- Client: `handleAppResumed` does not restart after an explicit stop,
  `record()` still lazily starts one, and `close()` drops the session and
  blocks later restarts

The envelope tests are untouched: the json_serializable conversion had to
satisfy them as written.

49 -> 57 dart, 14 -> 17 flutter.
Adds a matrix over every path that can end a session, asserting event type,
that the event's session section carries the ended session with its stop
timestamp and duration, and exact emission counts.

Emits once: explicit stopSession(), stopping a paused session, the session
timeout expiring under fakeAsync, close() on a running session, and
startSession() displacing a running session (asserting the displaced session is
the one reported).

Emits nothing: no session ever started (stop and close), stopSession() twice,
close() after a stop, close() after a timeout, the first startSession(), a
pause/resume inside the timeout, a resume after an explicit stop, and record()'s
lazy start after a stop.

Also covers a sender that suspends before failing on the session-stop event,
which is only caught because the emission awaits send() inside its own guard,
and asserts the client stays usable afterwards.

Existing client tests await stopSession()/close() now that they return
Future<void>. The envelope tests are untouched.
Extends the session boundary matrix to _session.start and renames the file,
which now covers both events.

Emits a start: at construction with autoSessionTracking on, on an explicit
startSession() after the displaced stop, on record()'s lazy start ahead of the
recorded event, and when a resume follows a session timeout. The start event's
session section carries the new session's id and start timestamp with no stop
fields, and gets the same enrichment and globals a recorded event gets.

Does not emit a start: at construction with autoSessionTracking off, on a
pause/resume inside the timeout window (same session), on a resume after an
explicit stop, and on any end path. A full timeout cycle asserts two starts and
two stops, interleaved, one pair per session and matched by session id.

Two ordering tests use a sender that logs when each send begins and completes,
which a synchronously-appending sender cannot distinguish: a displaced stop
completes before the new start begins, and a lazy start completes before
record()'s own send.

The sender-failure group now covers startSession() as well, and counts spell out
that both the start and stop attempts failed.

Existing client tests updated for the eager start now preceding the first
recorded event. The envelope tests are untouched.
`ConsoleEventSink` -> `ConsoleSender`, implementing `Sender` instead of
`EventSink`, and `sink:` -> `sender:` at the create() call.
stopSession() and close() now return Future<void>, completing once the session
stop event has been handed to the Sender.

dispose() cannot await, so it fires close() best-effort with a comment saying
so. The Close button awaits instead, so the log line follows the emitted event
rather than racing it, and a Stop Session button was added to make the
_session.stop envelope visible without closing the client.
Adds a Start Session button so the displacement pair is visible (the running
session's _session.stop, then the new session's _session.start), and documents
the full walkthrough for both event types in the example README.
@ekjotmultani
ekjotmultani force-pushed the feat/event-enrichment-client-example branch from c5c9e18 to c25df04 Compare August 21, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants