feat(FN-1862): add completion state tracking for onboarding

- Add markOnboardingCompleted() to set completedAt timestamp when user finishes onboarding
- Add isOnboardingCompleted() to check if onboarding was completed (vs dismissed)
- Update ModelOnboardingModal to call markOnboardingCompleted on successful completion
- Skip onboarding auto-open when already completed locally
- Add completion state tracking tests in ModelOnboardingModal.test.tsx
- Add model-onboarding-state unit tests
- Update useAuthOnboarding to check local completion state before auto-opening
- Document localStorage completion state tracking pattern in .fusion/memory.md
This commit is contained in:
Fusion
2026-04-14 23:44:40 -07:00
committed by gsxdsm
parent 6d685a542b
commit a51e75941c
49 changed files with 572 additions and 196 deletions

View File

@@ -34,9 +34,6 @@ export interface PushNotificationManagerOptions {
type PushNotificationsModule = typeof import("@capacitor/push-notifications");
/** Fallback listener type for untyped event handling */
type FallbackListener = (...args: unknown[]) => void;
export class PushNotificationManager extends EventEmitter {
private deviceToken: string | undefined;
private ntfyBaseUrl: string;
@@ -59,8 +56,8 @@ export class PushNotificationManager extends EventEmitter {
eventName: K,
listener: (payload: PushNotificationEventMap[K]) => void,
): this;
override on(eventName: string | symbol, listener: FallbackListener): this;
override on(eventName: string | symbol, listener: FallbackListener): this {
override on(eventName: string | symbol, listener: (...args: any[]) => void): this;
override on(eventName: string | symbol, listener: (...args: any[]) => void): this {
return super.on(eventName, listener);
}
@@ -68,8 +65,8 @@ export class PushNotificationManager extends EventEmitter {
eventName: K,
listener: (payload: PushNotificationEventMap[K]) => void,
): this;
override off(eventName: string | symbol, listener: FallbackListener): this;
override off(eventName: string | symbol, listener: FallbackListener): this {
override off(eventName: string | symbol, listener: (...args: any[]) => void): this;
override off(eventName: string | symbol, listener: (...args: any[]) => void): this {
return super.off(eventName, listener);
}