Skip to content

Commit 7daccf4

Browse files
Merge pull request #1439 from marcuscastelo/fix/use-before-initialization
Refactor Copilot instructions and enhance dependency injection
2 parents a3c4560 + 639bbed commit 7daccf4

File tree

52 files changed

+580
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+580
-388
lines changed

.github/copilot-instructions.md

Lines changed: 91 additions & 120 deletions
Large diffs are not rendered by default.

.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"type": "chrome",
99
"request": "launch",
1010
"name": "Launch Chrome against localhost",
11-
"url": "http://localhost:8080",
11+
"url": "http://localhost:3000",
1212
"webRoot": "${workspaceFolder}"
1313
}
1414
]
15-
}
15+
}

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@
7373
"file": ".github/copilot-commit-message-instructions.md"
7474
}
7575
],
76-
}
76+
}

.zed/debug.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Project-local debug tasks
2+
//
3+
// For more documentation on how to configure debug tasks,
4+
// see: https://zed.dev/docs/debugger
5+
[]

.zed/settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// For a full list of overridable settings, and general information on folder-specific settings,
44
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
55
{
6+
"tab_size": 2,
67
"languages": {
78
"TypeScript": {
89
"formatter": {
@@ -14,5 +15,16 @@
1415
"code_action": "source.fixAll.eslint"
1516
}
1617
}
18+
},
19+
"lsp": {
20+
"vtsls": {
21+
"settings": {
22+
"typescript": {
23+
"preferences": {
24+
"importModuleSpecifier": "non-relative"
25+
}
26+
}
27+
}
28+
}
1729
}
1830
}

biome.jsonc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.3.8/schema.json",
3+
"linter": {
4+
"rules": {
5+
"style": {
6+
"useImportType": "off"
7+
}
8+
}
9+
}
10+
}

src/app.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const BottomNavigation = lazy(async () => ({
3232

3333
function useAspectWidth() {
3434
const [width, setWidth] = createSignal(getWidth())
35+
3536
function getWidth() {
3637
return Math.min((window.innerHeight * 14) / 16, window.innerWidth)
3738
}

src/di/useCases.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { createEffect, createMemo, createRoot, createSignal } from 'solid-js'
2+
3+
import { createAuthUseCases } from '~/modules/auth/application/usecases/authUseCases'
4+
import { createUserUseCases } from '~/modules/user/application/usecases/userUseCases'
5+
import { type UserRepository } from '~/modules/user/domain/userRepository'
6+
import { createGuestUserRepository } from '~/modules/user/infrastructure/guest/guestUserRepository'
7+
import { createSupabaseUserRepository } from '~/modules/user/infrastructure/supabase/supabaseUserRepository'
8+
import { GUEST_USER_ID } from '~/shared/guest/guestConstants'
9+
import { createGuestUseCases } from '~/shared/guest/guestUseCases'
10+
11+
export type AppMode = 'guest' | 'normal'
12+
13+
const container = createRoot(() => {
14+
// TODO: Refactor global DI so that guestMode signal is not in the global DI container
15+
const [mode, setMode] = createSignal<AppMode>('normal')
16+
17+
const userUseCases = createMemo(() =>
18+
createUserUseCases({
19+
repository: () => getUserRepository(mode()),
20+
}),
21+
)
22+
23+
const authUseCases = createMemo(() =>
24+
createAuthUseCases({
25+
userUseCases: () => userUseCases(),
26+
}),
27+
)
28+
29+
const guestUseCases = createMemo(() =>
30+
createGuestUseCases({
31+
authUseCases: () => authUseCases(),
32+
}),
33+
)
34+
35+
createEffect(() => {
36+
const isGuest =
37+
authUseCases().currentUserIdOrGuestId() === GUEST_USER_ID &&
38+
guestUseCases().hasAcceptedGuestTerms()
39+
setMode(isGuest ? 'guest' : 'normal')
40+
})
41+
42+
function container() {
43+
return {
44+
userUseCases,
45+
guestUseCases,
46+
authUseCases,
47+
}
48+
}
49+
50+
return container()
51+
})
52+
53+
// TODO: Refactor global DI so that we don't need to switch repositories like this
54+
function getUserRepository(mode: AppMode): UserRepository {
55+
return mode === 'guest'
56+
? createGuestUserRepository()
57+
: createSupabaseUserRepository()
58+
}
59+
60+
export const useCases = {
61+
...container,
62+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { createEffect, createRoot } from 'solid-js'
2+
3+
import { createAuthService } from '~/modules/auth/application/services/authService'
4+
import { createAuthStore } from '~/modules/auth/application/store/authStore'
5+
import { createSupabaseAuthGateway } from '~/modules/auth/infrastructure/supabase/supabaseAuthGateway'
6+
import { showPromise } from '~/modules/toast/application/toastManager'
7+
import type { createUserUseCases } from '~/modules/user/application/usecases/userUseCases'
8+
9+
export type AuthDI = {
10+
userUseCases: () => ReturnType<typeof createUserUseCases>
11+
}
12+
13+
export function createAuthDI(di: AuthDI) {
14+
return createRoot(() => {
15+
const userUseCases = di.userUseCases()
16+
const authStore = createAuthStore()
17+
const authGateway = createSupabaseAuthGateway()
18+
const authService = createAuthService(authStore, authGateway, {
19+
fetchUser: userUseCases.fetchUser,
20+
insertUserSilently: userUseCases.insertUserSilently,
21+
forceSwitchToUser_unsafe: userUseCases.forceSwitchToUser_unsafe,
22+
})
23+
24+
createEffect(() => {
25+
const state = authStore.authState()
26+
showPromise(
27+
userUseCases
28+
.fetchUser(state.user?.id ?? '')
29+
.then(userUseCases.forceSwitchToUser_unsafe),
30+
{
31+
loading: 'Carregando dados do usuário...',
32+
error: 'Falha ao carregar dados do usuário',
33+
},
34+
{ context: 'background' },
35+
).catch(() => {})
36+
})
37+
38+
return { authStore, authService }
39+
})
40+
}

src/modules/auth/application/services/authService.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import {
55
type SignOutOptions,
66
} from '~/modules/auth/domain/auth'
77
import { type AuthGateway } from '~/modules/auth/domain/authGateway'
8-
import { createSupabaseAuthGateway } from '~/modules/auth/infrastructure/supabase/supabaseAuthGateway'
98
import { showError } from '~/modules/toast/application/toastManager'
10-
import { userUseCases } from '~/modules/user/application/usecases/userUseCases'
11-
import { createNewUser, type NewUser } from '~/modules/user/domain/user'
9+
import {
10+
createNewUser,
11+
type NewUser,
12+
type User,
13+
} from '~/modules/user/domain/user'
1214
import { logging } from '~/shared/utils/logging'
1315

1416
/**
@@ -41,7 +43,12 @@ function generateDefaultUserFromSession(session: AuthSession): NewUser {
4143

4244
export function createAuthService(
4345
authStore: AuthStore,
44-
authGateway: AuthGateway = createSupabaseAuthGateway(),
46+
authGateway: AuthGateway,
47+
useCases: {
48+
fetchUser: (userId: User['uuid']) => Promise<User | null>
49+
insertUserSilently: (newUser: NewUser) => Promise<User | null>
50+
forceSwitchToUser_unsafe: (user: User) => void
51+
},
4552
) {
4653
async function signIn(options: SignInOptions): Promise<void> {
4754
try {
@@ -119,7 +126,7 @@ export function createAuthService(
119126
}))
120127

121128
if (session?.user.id !== undefined) {
122-
userUseCases
129+
useCases
123130
.fetchUser(session.user.id)
124131
.then(async (user) => {
125132
logging.debug('User: ', { user })
@@ -128,10 +135,9 @@ export function createAuthService(
128135
'User profile not found, creating default profile for OAuth user',
129136
)
130137
const newUser = generateDefaultUserFromSession(session)
131-
const createdUser =
132-
await userUseCases.insertUserSilently(newUser)
138+
const createdUser = await useCases.insertUserSilently(newUser)
133139
if (createdUser !== null) {
134-
userUseCases.forceSwitchToUser_unsafe(createdUser)
140+
useCases.forceSwitchToUser_unsafe(createdUser)
135141
logging.info('User profile created successfully')
136142
} else {
137143
showError(

0 commit comments

Comments
 (0)