680 lines
21 KiB
Markdown
680 lines
21 KiB
Markdown
# Flutter Project Rewrite Refactor Playbook
|
|
|
|
## Purpose
|
|
|
|
This document adapts the generic "rewrite by a different engineer" refactor template to the current `pets_hero_ai` Flutter app.
|
|
|
|
The goal is a structural rewrite that makes the project look and feel newly organized while preserving behavior:
|
|
|
|
- UI output stays visually equivalent.
|
|
- API requests, parameters, encryption, authentication, payment, attribution, and analytics behavior stay equivalent.
|
|
- Existing app startup, login, referrer, home loading, generation, gallery, recharge, and profile flows keep working.
|
|
- The project compiles after each module migration.
|
|
|
|
This is not a feature rewrite. It is a controlled architecture migration.
|
|
|
|
## Current Project Shape
|
|
|
|
Current code is already partially feature-first:
|
|
|
|
- `lib/core/`
|
|
- API client, proxy encryption, auth, token storage, referrer, Adjust/Facebook events, theme, logging, user state.
|
|
- `lib/features/`
|
|
- `home`, `gallery`, `generate_video`, `recharge`, `profile`.
|
|
- `lib/shared/`
|
|
- shared tab selector and common widgets.
|
|
- Entrypoints:
|
|
- `lib/main.dart`
|
|
- `lib/app.dart`
|
|
|
|
Because the app already uses a `core/features/shared` layout, a plain Feature-first migration would not be different enough. The recommended target architecture is therefore a Clean Architecture-lite layout with vertical modules.
|
|
|
|
## Recommended Architecture
|
|
|
|
Choose this as the default unless there is a strong reason not to:
|
|
|
|
**Clean Architecture-lite + Vertical Modules**
|
|
|
|
Target layout:
|
|
|
|
```text
|
|
lib/
|
|
bootstrap/
|
|
main_bootstrap.dart
|
|
platform_startup.dart
|
|
|
|
app_shell/
|
|
pets_hero_app.dart
|
|
routes/
|
|
route_table.dart
|
|
route_observer.dart
|
|
lifecycle/
|
|
facebook_lifecycle_reporter.dart
|
|
|
|
foundation/
|
|
analytics/
|
|
adjust_event_gateway.dart
|
|
facebook_event_gateway.dart
|
|
auth/
|
|
device_identity_provider.dart
|
|
session_bootstrapper.dart
|
|
token_vault.dart
|
|
config/
|
|
api_environment.dart
|
|
facebook_environment.dart
|
|
logging/
|
|
tagged_log.dart
|
|
network/
|
|
api_response.dart
|
|
encrypted_proxy_client.dart
|
|
proxy_crypto.dart
|
|
service_locator.dart
|
|
referrer/
|
|
install_referrer_probe.dart
|
|
attribution_digest_builder.dart
|
|
attribution_polling_coordinator.dart
|
|
theme/
|
|
colors.dart
|
|
spacing.dart
|
|
typography.dart
|
|
theme_factory.dart
|
|
user/
|
|
account_state.dart
|
|
account_refresh_use_case.dart
|
|
device/
|
|
memory_profile.dart
|
|
|
|
modules/
|
|
home/
|
|
domain/
|
|
entities/
|
|
policies/
|
|
data/
|
|
home_catalog_api.dart
|
|
mappers/
|
|
application/
|
|
home_catalog_controller.dart
|
|
playback_visibility_coordinator.dart
|
|
presentation/
|
|
home_view.dart
|
|
components/
|
|
|
|
gallery/
|
|
domain/
|
|
data/
|
|
application/
|
|
presentation/
|
|
|
|
creation/
|
|
domain/
|
|
data/
|
|
application/
|
|
presentation/
|
|
generate_view.dart
|
|
progress_view.dart
|
|
result_view.dart
|
|
camera_view.dart
|
|
components/
|
|
|
|
billing/
|
|
domain/
|
|
data/
|
|
application/
|
|
presentation/
|
|
recharge_view.dart
|
|
points_history_view.dart
|
|
payment_webview_view.dart
|
|
|
|
profile/
|
|
domain/
|
|
data/
|
|
application/
|
|
presentation/
|
|
|
|
ui_kit/
|
|
navigation/
|
|
media/
|
|
badges/
|
|
tabs/
|
|
```
|
|
|
|
Mapping from current structure:
|
|
|
|
| Current | Target |
|
|
| --- | --- |
|
|
| `core/api/*` | `foundation/network/*` and module-specific `data/*_api.dart` |
|
|
| `core/auth/*` | `foundation/auth/*` |
|
|
| `core/referrer/*` | `foundation/referrer/*` |
|
|
| `core/adjust/*` | `foundation/analytics/*` |
|
|
| `core/theme/*` | `foundation/theme/*` |
|
|
| `core/user/*` | `foundation/user/*` |
|
|
| `shared/widgets/*` | `ui_kit/*` or module `presentation/components/*` |
|
|
| `features/home/*` | `modules/home/{domain,data,application,presentation}` |
|
|
| `features/generate_video/*` | `modules/creation/{domain,data,application,presentation}` |
|
|
| `features/recharge/*` | `modules/billing/{domain,data,application,presentation}` |
|
|
| `features/gallery/*` | `modules/gallery/{domain,data,application,presentation}` |
|
|
| `features/profile/*` | `modules/profile/{domain,data,application,presentation}` |
|
|
| `app.dart` | `app_shell/pets_hero_app.dart` |
|
|
| `main.dart` | `bootstrap/main_bootstrap.dart` plus thin `main.dart` |
|
|
|
|
## Architecture Choice Gate
|
|
|
|
Before implementation, choose one final target:
|
|
|
|
1. **Recommended: Clean Architecture-lite + Vertical Modules**
|
|
- Best fit because current project is already feature-first.
|
|
- Produces a clearly different layout while avoiding heavy dependency injection frameworks.
|
|
2. **Strict Clean Architecture**
|
|
- Adds explicit repository interfaces and use cases for every module.
|
|
- More ceremony, higher migration cost.
|
|
3. **MVVM + Repository**
|
|
- Good if UI state should be centralized in view models.
|
|
- Useful if future code will replace large `StatefulWidget` files with controllers.
|
|
4. **Custom**
|
|
- Must still define boundaries for app shell, foundation, modules, and UI kit before code is moved.
|
|
|
|
If uncertain, use option 1.
|
|
|
|
## Non-Negotiable Behavior Invariants
|
|
|
|
Preserve these exactly:
|
|
|
|
- Startup order:
|
|
- `ensureDeviceMemoryProfileInitialized`
|
|
- Adjust initialization
|
|
- first frame and native splash removal
|
|
- `AuthService` equivalent login bootstrap
|
|
- Android Google Play pending purchase listener
|
|
- order recovery after successful login
|
|
- API transport:
|
|
- encrypted proxy request wrapper
|
|
- V2 `sanctum` payload structure
|
|
- existing path, method, query, body semantics
|
|
- timeout and error behavior
|
|
- Authentication:
|
|
- device ID selection
|
|
- MD5 sign calculation
|
|
- local token restore/write
|
|
- fast login retry and failure telemetry
|
|
- Attribution:
|
|
- Adjust init and attribution callback
|
|
- Play Install Referrer fallback
|
|
- organic polling behavior
|
|
- post-login referrer reporting
|
|
- `common_info` refresh and home reload behavior
|
|
- Analytics:
|
|
- Adjust event tokens
|
|
- Facebook App Events names and parameters
|
|
- manual `activateApp`
|
|
- Facebook app install check log
|
|
- UI:
|
|
- same routes
|
|
- same navigation tabs
|
|
- same home/category/task loading behavior
|
|
- same recharge, gallery, generation, and profile behavior
|
|
- Payments:
|
|
- Google Play purchase stream subscription timing
|
|
- pending order recovery
|
|
- verification payloads
|
|
- webview payment polling behavior
|
|
|
|
## Call Sequence Invariants
|
|
|
|
Directory moves, class renames, and file splitting must not change async ordering. Treat the following sequences as contract tests.
|
|
|
|
### Cold Startup Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. `WidgetsFlutterBinding.ensureInitialized()`.
|
|
2. Device memory profile initialization.
|
|
3. Adjust SDK initialization and attribution callback registration.
|
|
4. System UI overlay style setup.
|
|
5. `runApp(...)`.
|
|
6. Authentication bootstrap starts after `runApp`.
|
|
7. Android-only pending Google Play purchase listener starts immediately after auth bootstrap is kicked off.
|
|
8. Order recovery waits for login completion and only runs when startup succeeded.
|
|
9. First frame removes native splash, logs Facebook app install state, then reports Facebook `activateApp`.
|
|
|
|
Do not move auth bootstrap before `runApp`, do not delay the Google Play listener until after login, and do not run order recovery before login completion.
|
|
|
|
### Login and Initial API Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. Short startup delay.
|
|
2. Resolve device ID.
|
|
3. Compute MD5 sign from device ID.
|
|
4. Resolve first referrer digest:
|
|
- race Adjust attribution timeout/callback;
|
|
- fallback to Play Install Referrer on Android.
|
|
5. Restore local auth token into the API client.
|
|
6. Call `POST /v1/user/fast_login` with:
|
|
- `origin`;
|
|
- `resolution`;
|
|
- `digest`.
|
|
7. On success:
|
|
- persist returned user token if present;
|
|
- send register events only when first-register flag is true;
|
|
- update credits/user/country state;
|
|
- start post-login referrer/common-info work in the background;
|
|
- mark startup succeeded.
|
|
8. On failure:
|
|
- mark startup failed;
|
|
- emit `LoginFaild` Facebook event once from the startup failure path.
|
|
|
|
Do not call authenticated business APIs before token restore and `fast_login` handling have reached the same point as before.
|
|
|
|
### Post-Login Referrer and Common Info Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. Call `GET/SDK Adjust.getAttribution()` equivalent and build the Adjust digest.
|
|
2. Read Play Install Referrer digest.
|
|
3. Call `POST /v1/user/referrer` with `accolade=android_adjust`.
|
|
4. Call `POST /v1/user/referrer` with `accolade=gg`.
|
|
5. Call `GET /v1/user/common_info`.
|
|
6. Apply `common_info` fields into user/global state.
|
|
7. If home structure changed, request full home reload.
|
|
8. Start organic attribution polling only after this first post-login sequence has completed.
|
|
|
|
Organic polling end behavior to preserve:
|
|
|
|
1. Poll every 5 seconds.
|
|
2. Stop when attribution becomes non-organic or 5 minutes elapsed.
|
|
3. After polling stops, always rerun:
|
|
- `POST /v1/user/referrer` with `accolade=android_adjust`;
|
|
- `POST /v1/user/referrer` with `accolade=gg`;
|
|
- `GET /v1/user/common_info`.
|
|
4. Only after the rerun finishes, trigger home full reload so `GET /v1/image/img2video/categories` is requested with the refreshed server-side state.
|
|
|
|
Do not make the category refresh race ahead of referrer/common-info reporting.
|
|
|
|
### Home Loading Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. Home view may be created before login finishes.
|
|
2. Category loading waits for login completion.
|
|
3. Call `GET /v1/image/img2video/categories`.
|
|
4. If `need_wait == true`, append the local `pets` pseudo-category.
|
|
5. Select the first category.
|
|
6. If the selected category is not `pets`, call `GET /v1/image/img2video/tasks`.
|
|
7. If the selected category is `pets`, use `extConfig.items` and do not call task list for `pets`.
|
|
8. After category/task updates, refresh playback visibility.
|
|
|
|
`UserState.requestHomeFullReload()` or its renamed equivalent must still re-enter this category loading sequence.
|
|
|
|
### Payment Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. Android purchase stream listener starts early during app startup.
|
|
2. Google Play order recovery runs after login completion and only after successful startup.
|
|
3. Recharge purchase actions still emit tier/purchase events at the same user action points.
|
|
4. Successful purchase verification updates account state before user-visible balance-dependent UI relies on it.
|
|
5. Purchase success/failure Adjust and Facebook events keep the same event names/tokens and relative timing.
|
|
6. Third-party payment webview polling keeps the same retry intervals and terminal status handling.
|
|
|
|
### Navigation and Lifecycle Sequence
|
|
|
|
Current order to preserve:
|
|
|
|
1. Route names remain stable unless every navigation caller and documentation reference is migrated together.
|
|
2. Returning to home still resumes playback through the home playback nonce flow.
|
|
3. Foreground resume still reports Facebook `activateApp`.
|
|
4. Media picker flows still temporarily disable screen protection and restore it afterward.
|
|
|
|
## Refactor Rules
|
|
|
|
### Allowed
|
|
|
|
- Move files to new directories.
|
|
- Split large files by concern.
|
|
- Rename private classes, helpers, and variables when imports are updated.
|
|
- Rename public widget classes if all route references and imports are updated in the same step.
|
|
- Introduce barrel files only when they reduce noisy imports.
|
|
- Extract controllers/coordinators from large `StatefulWidget` files.
|
|
- Replace direct helper calls with small application-layer coordinator classes when behavior is unchanged.
|
|
|
|
### Not Allowed
|
|
|
|
- Changing endpoint paths, request parameters, event names, token keys, or analytics event tokens.
|
|
- Changing local storage keys unless a migration is added.
|
|
- Changing route names without updating all navigation callers.
|
|
- Changing product IDs, purchase completion behavior, or order recovery timing.
|
|
- Changing image/video playback rules while moving code.
|
|
- Adding new state-management packages only for the refactor.
|
|
- Reformatting or rewriting generated/platform files unrelated to the migration.
|
|
|
|
## File Splitting Targets
|
|
|
|
Prioritize these files because they currently carry several responsibilities:
|
|
|
|
- `lib/app.dart`
|
|
- App widget, route table, lifecycle reporting, startup overlay, main scaffold.
|
|
- Split into app shell, routes, lifecycle reporter, startup overlay, main scaffold.
|
|
- `lib/core/auth/auth_service.dart`
|
|
- Device identity, token restore, login retry, common info, referrer reporting, screen security.
|
|
- Split into session bootstrapper, device identity provider, token vault, common info synchronizer, referrer post-login coordinator.
|
|
- `lib/core/referrer/referrer_service.dart`
|
|
- Adjust digest, Play referrer, organic polling.
|
|
- Split into attribution digest builder, install referrer probe, attribution polling coordinator.
|
|
- `lib/features/home/home_screen.dart`
|
|
- Category loading, task loading, ext config parsing, playback visibility, UI layout.
|
|
- Split into home controller, catalog data source, playback visibility coordinator, home view components.
|
|
- `lib/features/generate_video/generate_video_screen.dart`
|
|
- UI, upload, creation request, media selection, camera/album coordination.
|
|
- Split into creation flow controller, upload coordinator, prompt/media components.
|
|
- `lib/features/recharge/recharge_screen.dart`
|
|
- Product rendering, purchase flow, third-party payment, event reporting.
|
|
- Split into billing controller, purchase coordinator, payment option components.
|
|
|
|
## Suggested Migration Order
|
|
|
|
Work in small batches. After each batch, run analysis and at least one release/debug build smoke check.
|
|
|
|
### Phase 0: Baseline
|
|
|
|
Capture current behavior before moving code:
|
|
|
|
- Run `flutter analyze`.
|
|
- Run the app with trace logs:
|
|
- `flutter run --release --dart-define=APP_LOG_LEVEL=trace`
|
|
- Verify logs for:
|
|
- Adjust init and attribution callback.
|
|
- Facebook install check.
|
|
- fast login.
|
|
- referrer reporting.
|
|
- `common_info`.
|
|
- categories and first task load.
|
|
- purchase listener startup on Android.
|
|
|
|
### Phase 1: App Shell
|
|
|
|
Move without changing behavior:
|
|
|
|
- `main.dart` becomes a thin entrypoint.
|
|
- App widget moves to `app_shell/pets_hero_app.dart`.
|
|
- Route definitions move to `app_shell/routes/route_table.dart`.
|
|
- Route observer moves to `app_shell/routes/route_observer.dart`.
|
|
- Startup overlay moves to `app_shell/lifecycle/startup_overlay.dart`.
|
|
- Facebook lifecycle/install-check logic moves to `app_shell/lifecycle/facebook_lifecycle_reporter.dart`.
|
|
|
|
Validation:
|
|
|
|
- App opens to the same tab.
|
|
- Native splash is removed at the same time.
|
|
- `activateApp` and install check logs still appear.
|
|
|
|
### Phase 2: Foundation Network and Config
|
|
|
|
Move:
|
|
|
|
- API config, API client, proxy client, crypto, response type.
|
|
- Logging.
|
|
- Facebook/Adjust config.
|
|
|
|
Validation:
|
|
|
|
- `fast_login`, `common_info`, category/task requests still show identical paths and body shapes in trace logs.
|
|
- No endpoint path changes.
|
|
|
|
### Phase 3: Foundation Auth and Attribution
|
|
|
|
Move and split:
|
|
|
|
- Auth/session bootstrapper.
|
|
- Device identity and sign generation.
|
|
- Token vault.
|
|
- Referrer digest and polling.
|
|
- Adjust/Facebook event gateways.
|
|
|
|
Validation:
|
|
|
|
- New install and returning-user startup both work.
|
|
- Natural/organic attribution polling still runs every 5s and stops after 5min or non-organic attribution.
|
|
- After polling stops, referrer is reported, `common_info` refreshes, then categories reload.
|
|
|
|
### Phase 4: UI Kit
|
|
|
|
Move shared visual widgets:
|
|
|
|
- Bottom navigation.
|
|
- Top navigation.
|
|
- Credits badge.
|
|
- Tab selector scope or replacement shell coordinator.
|
|
|
|
Validation:
|
|
|
|
- Bottom tabs, top bar, credits display, and route behavior are unchanged.
|
|
|
|
### Phase 5: Home Module
|
|
|
|
Move and split:
|
|
|
|
- Entities:
|
|
- category item
|
|
- task item
|
|
- ext config item
|
|
- Data:
|
|
- category/task API wrappers
|
|
- JSON mappers
|
|
- Application:
|
|
- category/task loading coordinator
|
|
- ext config policy
|
|
- playback visibility coordinator
|
|
- Presentation:
|
|
- home view
|
|
- tab row
|
|
- video card
|
|
|
|
Validation:
|
|
|
|
- `need_wait` behavior unchanged.
|
|
- `pets` pseudo-category behavior unchanged.
|
|
- Video autoplay visibility behavior unchanged.
|
|
- `UserState.requestHomeFullReload()` still reloads categories and tasks.
|
|
|
|
### Phase 6: Creation Module
|
|
|
|
Move:
|
|
|
|
- Generate screen.
|
|
- Progress screen.
|
|
- Result screen.
|
|
- In-app camera page.
|
|
- Album picker.
|
|
- Image compression helpers if only used by creation.
|
|
|
|
Validation:
|
|
|
|
- Album/camera selection works.
|
|
- Upload and task creation request shapes are unchanged.
|
|
- Progress polling and result navigation are unchanged.
|
|
|
|
### Phase 7: Gallery Module
|
|
|
|
Move:
|
|
|
|
- Gallery screen.
|
|
- Gallery task item.
|
|
- Upload cover store.
|
|
- Thumbnail cache.
|
|
|
|
Validation:
|
|
|
|
- Gallery loads the same data.
|
|
- Video thumbnails/cache behavior unchanged.
|
|
- Navigation to result/generate flows unchanged.
|
|
|
|
### Phase 8: Billing Module
|
|
|
|
Move:
|
|
|
|
- Recharge screen.
|
|
- Payment webview.
|
|
- Points history.
|
|
- Google Play purchase service.
|
|
- Payment models.
|
|
|
|
Validation:
|
|
|
|
- Products render the same.
|
|
- Google Play purchase and pending purchase recovery work.
|
|
- Third-party payment webview flow works.
|
|
- Purchase success/failure Adjust and Facebook events are unchanged.
|
|
|
|
### Phase 9: Profile Module
|
|
|
|
Move:
|
|
|
|
- Profile screen.
|
|
- Account deletion / account display dependencies if any.
|
|
|
|
Validation:
|
|
|
|
- Profile data, recharge navigation, account actions are unchanged.
|
|
|
|
### Phase 10: Cleanup
|
|
|
|
- Remove old empty directories.
|
|
- Remove transitional imports.
|
|
- Keep barrel files minimal.
|
|
- Update docs that reference old paths:
|
|
- `docs/app_startup.md`
|
|
- `docs/home.md`
|
|
- `docs/payment_flow.md`
|
|
- `docs/generate_video.md`
|
|
- `docs/user_login.md`
|
|
|
|
## Import Strategy
|
|
|
|
Use package imports for cross-module references:
|
|
|
|
```dart
|
|
import 'package:pets_hero_ai/foundation/network/api_response.dart';
|
|
import 'package:pets_hero_ai/modules/home/presentation/home_view.dart';
|
|
```
|
|
|
|
Avoid long chains of relative imports across modules.
|
|
|
|
Optional barrel files:
|
|
|
|
```text
|
|
foundation/network/network.dart
|
|
modules/home/home.dart
|
|
modules/billing/billing.dart
|
|
ui_kit/ui_kit.dart
|
|
```
|
|
|
|
Use a barrel only when at least three external files import the same group.
|
|
|
|
## Naming Style
|
|
|
|
Use a noticeably different naming style while keeping semantics clear:
|
|
|
|
- `AuthService` → `SessionBootstrapper`
|
|
- `ReferrerService` → `AttributionCoordinator`
|
|
- `ImageApi` category/task calls → `HomeCatalogApi`
|
|
- `UserState` → `AccountState`
|
|
- `AdjustEvents` → `MarketingEventGateway`
|
|
- `HomeScreen` → `HomeView`
|
|
- `GenerateVideoScreen` → `CreationView`
|
|
- `RechargeScreen` → `BillingView`
|
|
|
|
Prefer:
|
|
|
|
- `Coordinator` for orchestration.
|
|
- `Gateway` for third-party SDK/event wrappers.
|
|
- `Probe` for platform capability checks.
|
|
- `Vault` for local secure-ish persistence.
|
|
- `Policy` for pure decision logic.
|
|
- `Mapper` for JSON conversion.
|
|
|
|
## State Management Guidance
|
|
|
|
Do not add Bloc/Riverpod/Provider just to make the rewrite look different.
|
|
|
|
For this project, prefer lightweight application-layer controllers:
|
|
|
|
- Keep existing `ValueNotifier`-based global state where behavior depends on it.
|
|
- Extract complex `StatefulWidget` logic into controllers that are owned by the widget state.
|
|
- Use `ListenableBuilder`/`ValueListenableBuilder` where the existing behavior already relies on notifiers.
|
|
- Only replace `setState` when the extracted controller makes ownership clearer.
|
|
|
|
## Verification Checklist Per Phase
|
|
|
|
Run:
|
|
|
|
```sh
|
|
flutter analyze
|
|
```
|
|
|
|
For Android smoke checks:
|
|
|
|
```sh
|
|
flutter run --release --dart-define=APP_LOG_LEVEL=trace
|
|
```
|
|
|
|
Check logs for changed phases:
|
|
|
|
- Request paths and query/body fields.
|
|
- Auth/referrer/common_info sequence.
|
|
- Adjust/Facebook events.
|
|
- Home category/task reloads.
|
|
- Purchase listener and recovery startup.
|
|
|
|
For every phase that touches startup, auth, referrer, home, or billing, compare the trace log against a pre-refactor baseline. The comparison must verify order, not only presence:
|
|
|
|
```text
|
|
Adjust init
|
|
runApp
|
|
Auth bootstrap
|
|
Google Play listener
|
|
fast_login
|
|
post-login referrer(android_adjust)
|
|
post-login referrer(gg)
|
|
common_info
|
|
categories
|
|
tasks, when applicable
|
|
organic polling stop
|
|
referrer(android_adjust)
|
|
referrer(gg)
|
|
common_info
|
|
categories
|
|
```
|
|
|
|
If any request appears earlier/later than the baseline, stop the migration and decide explicitly whether the order change is acceptable. The default answer is no.
|
|
|
|
Manual UI checks:
|
|
|
|
- App launch.
|
|
- Home list and tabs.
|
|
- Generate flow.
|
|
- Gallery flow.
|
|
- Recharge flow.
|
|
- Profile flow.
|
|
|
|
## Recommended Work Protocol
|
|
|
|
1. Move one module or one foundation slice at a time.
|
|
2. Keep old behavior tests/manual traces open while migrating.
|
|
3. Update imports immediately after every move.
|
|
4. Run analyzer before continuing to the next phase.
|
|
5. Do not combine architecture moves with feature fixes.
|
|
6. If a behavior bug is discovered, document it separately and decide whether to fix before or after migration.
|
|
7. Commit after each compiling phase if using git commits.
|
|
|
|
## Completion Criteria
|
|
|
|
The refactor is complete only when:
|
|
|
|
- No imports reference the old `core/`, `features/`, or `shared/` directories unless those directories intentionally remain as compatibility shims.
|
|
- The app compiles cleanly.
|
|
- Startup, login, attribution, home reload, generation, gallery, recharge, and profile flows match baseline behavior.
|
|
- Trace logs show the same API paths and event names as before.
|
|
- Old large files have been split along the target architecture boundaries.
|
|
- Docs and any route/import examples use the new paths.
|
|
|