-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor dependency injection and implement backward compatibility #1450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
marcuscastelo
wants to merge
28
commits into
rc/v0.16.0
Choose a base branch
from
marcuscastelo/issue1447
base: rc/v0.16.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,091
−1,473
Open
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
3aaceb4
fix(package): remove unnecessary command from test script
marcuscastelo ba77e98
feat(container): implement dependency injection container and provide…
marcuscastelo 0d90b17
refactor(di): batch 1 - user & container wiring
marcuscastelo 3159e61
refactor(di): auth usecases shim
marcuscastelo 323e037
docs(di): add DI migration plan
marcuscastelo 4e300d9
refactor(di): batch 2 - recipe crud factory + shims
marcuscastelo 74c193e
refactor(di): batch 2 - food crud factory + shims
marcuscastelo 1d024d7
refactor(di): batch 2 - meal usecases factory + shim
marcuscastelo 3bbc71c
refactor(di): batch 2 - day and meal typing + meal factory
marcuscastelo 22d36b6
refactor(di): batch 2 - meal uses DayUseCases type
marcuscastelo 77a080e
refactor(di): batch 2 - macro-profile service & usecases factories + …
marcuscastelo b882ae3
refactor(di): batch 2 - macro-profile factories + shims
marcuscastelo 78e9ad7
refactor(di): batch 2 - dayUseCases factory + shim
marcuscastelo fad6fb6
refactor(di): batch 2 - dedupe DayUseCases export
marcuscastelo b47a1fa
refactor(di): update migration progress checklist and document batch …
marcuscastelo 0d22e1f
refactor(di): batch-3 - day-diet & template-search factories + shims …
marcuscastelo 2cdecde
docs(di): mark batch-3 completed in DI-migration-plan.md
marcuscastelo 207f722
refactor(di): batch-4 - weight usecases factory + shim
marcuscastelo b7247c2
refactor(di): batch-5 - toast manager factory + shim (make testable)
marcuscastelo 5f81d81
refactor(di): batch-5 - recent-food CRUD factory + shim
marcuscastelo fbba9d1
refactor(di): batch-5 - clipboard usecases factory + shim
marcuscastelo 7a8b615
docs(di): update migration plan with assistant migration snapshot and…
marcuscastelo 85688a5
refactor(di): batch-6 - profile/search/observability factories + shims
marcuscastelo 807ae78
refactor(di): batch-4/5 - weight & measure factories + shims (part of…
marcuscastelo d2e6cfd
refactor(di): batch-4/5 - measure state + measure crud factory + weig…
marcuscastelo 3f3cdcc
refactor(di): batch-C/B - migrate macro-target & macro-overflow to fa…
marcuscastelo d313d05
docs(di): update migration checklist - mark batch 4/5/6 items done
marcuscastelo 17708e4
refactor(macro-nutrients): add legacy named exports for backward comp…
marcuscastelo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| import { createContext, type JSXElement, useContext } from 'solid-js' | ||
|
|
||
| import { createAuthUseCases } from '~/modules/auth/application/usecases/authUseCases' | ||
| import { createUserUseCases } from '~/modules/user/application/usecases/userUseCases' | ||
| import { createSupabaseUserRepository } from '~/modules/user/infrastructure/supabase/supabaseUserRepository' | ||
|
|
||
| /** | ||
| * Minimal interfaces for commonly-used use-cases. | ||
| * Keep these small and extend as consumers need more functionality. | ||
| */ | ||
| export type AuthUseCases = { | ||
| /** | ||
| * Initialize authentication lifecycle (listeners, session restore, etc). | ||
| * Should be safe to call multiple times. | ||
| */ | ||
| initializeAuth: () => void | ||
|
|
||
| /** | ||
| * Optional helper used for guest detection in legacy flows. | ||
| */ | ||
| currentUserIdOrGuestId?: () => string | null | ||
|
|
||
| [key: string]: unknown | ||
| } | ||
|
|
||
| export type UserUseCases = { | ||
| [key: string]: unknown | ||
| } | ||
|
|
||
| export type GuestUseCases = { | ||
| hasAcceptedGuestTerms?: () => boolean | ||
| [key: string]: unknown | ||
| } | ||
|
|
||
| /** | ||
| * Central DI container shape used by UI layer. | ||
| * | ||
| * Notes: | ||
| * - Prefer exposing factories or plain objects; avoid embedding ephemeral UI | ||
| * state (signals) inside the container. | ||
| * - Tests/SSR can call `createContainer(overrides)` to replace implementations. | ||
| */ | ||
| export type Container = { | ||
| authUseCases: AuthUseCases | ||
| userUseCases: UserUseCases | ||
| guestUseCases: GuestUseCases | ||
|
|
||
| /** | ||
| * Optional lifecycle hook for realtime or other infra that must be started | ||
| * when the app boots (Providers may call this if present). | ||
| */ | ||
| initializeWeightRealtime?: () => void | ||
|
|
||
| [key: string]: unknown | ||
| } | ||
|
|
||
| /** | ||
| * Create a container with sane defaults. Callers may provide partial overrides | ||
| * to replace concrete implementations (useful for tests and SSR). | ||
| * | ||
| * The returned container is intended to be created once and reused as the | ||
| * Context value for the app. Avoid creating a new container on every render. | ||
| */ | ||
| export function createContainer( | ||
| overrides: Partial<Container> = {}, | ||
| ): Readonly<Container> { | ||
| // Create default implementations using factories. These defaults are plain | ||
| // objects (not signals) and are safe to reuse as the container's defaults. | ||
| // Consumers and tests can override any of these via `overrides`. | ||
| const defaultUserUseCases = createUserUseCases({ | ||
| repository: () => createSupabaseUserRepository(), | ||
| }) | ||
|
|
||
| const defaultAuthUseCases: AuthUseCases = createAuthUseCases({ | ||
| userUseCases: () => defaultUserUseCases, | ||
| }) | ||
|
|
||
| const base: Container = { | ||
| authUseCases: defaultAuthUseCases, | ||
| userUseCases: defaultUserUseCases, | ||
| guestUseCases: {}, | ||
| initializeWeightRealtime: undefined, | ||
| } | ||
|
|
||
| // Merge defaults with overrides. The result satisfies `Container`. | ||
| const merged: Container = { | ||
| ...base, | ||
| ...overrides, | ||
| } | ||
|
|
||
| // Freeze to discourage accidental mutation at runtime. | ||
| Object.freeze(merged) | ||
|
|
||
| return merged | ||
| } | ||
|
|
||
| /** | ||
| * Solid context holding the container instance. | ||
| * Consumers should call `useContainer()` to access services. | ||
| */ | ||
| const ContainerContext = createContext<Readonly<Container> | null>(null) | ||
|
|
||
| /** | ||
| * Provider component that exposes the app container. | ||
| * | ||
| * Usage: | ||
| * const container = createContainer({ authUseCases: myAuth }) | ||
| * <ContainerProvider value={container}>{children}</ContainerProvider> | ||
| * | ||
| * Note: pass a stable container instance (do not recreate it on each render). | ||
| */ | ||
| /* eslint-disable solid/reactivity */ | ||
| export function ContainerProvider(props: { | ||
| value: Readonly<Container> | ||
| children?: JSXElement | ||
| }) { | ||
| return ( | ||
| <ContainerContext.Provider value={props.value}> | ||
| {props.children} | ||
| </ContainerContext.Provider> | ||
| ) | ||
| } | ||
| /* eslint-enable solid/reactivity */ | ||
|
|
||
| /** | ||
| * Hook to access the current container. Throws when used without a provider. | ||
| * | ||
| * Prefer passing explicit dependencies into domain/use-case factories rather | ||
| * than calling `useContainer()` deep inside pure domain logic. | ||
| */ | ||
| export function useContainer(): Readonly<Container> { | ||
| const ctx = useContext(ContainerContext) | ||
| if (!ctx) { | ||
| throw new Error( | ||
| 'Container not provided. Wrap the app with <ContainerProvider value={createContainer(...)}/>.', | ||
| ) | ||
| } | ||
| return ctx | ||
| } | ||
|
|
||
| /** | ||
| * Small helper to create a test container quickly. Tests should explicitly | ||
| * override only the services they need. | ||
| */ | ||
| export function createTestContainer( | ||
| overrides: Partial<Container> = {}, | ||
| ): Readonly<Container> { | ||
| const testAuth: AuthUseCases = { | ||
| initializeAuth: () => { | ||
| /* no-op */ | ||
| }, | ||
| currentUserIdOrGuestId: () => null, | ||
| } | ||
|
|
||
| return createContainer({ | ||
| authUseCases: testAuth, | ||
| userUseCases: {}, | ||
| guestUseCases: {}, | ||
| ...overrides, | ||
| }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test script no longer runs
gen-app-versionbefore tests, but other scripts likebuildstill depend on it. If tests rely on the generated app version (e.g., for version assertions or exports), they may fail. Verify that tests don't require the app version to be generated, or document why this change is safe.