diff --git a/exercises/01.basics/01.problem.install-and-configure/package.json b/exercises/01.basics/01.problem.install-and-configure/package.json
deleted file mode 100644
index d2c7f32..0000000
--- a/exercises/01.basics/01.problem.install-and-configure/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "name": "exercises_01.basics_01.problem.install-and-configure"
-}
diff --git a/exercises/01.basics/README.mdx b/exercises/01.basics/README.mdx
deleted file mode 100644
index a5e602c..0000000
--- a/exercises/01.basics/README.mdx
+++ /dev/null
@@ -1 +0,0 @@
-# Basics
\ No newline at end of file
diff --git a/exercises/01.basics/01.problem.install-and-configure/README.mdx b/exercises/01.fundamentals/01.problem.install-and-configure/README.mdx
similarity index 100%
rename from exercises/01.basics/01.problem.install-and-configure/README.mdx
rename to exercises/01.fundamentals/01.problem.install-and-configure/README.mdx
diff --git a/exercises/01.fundamentals/01.problem.install-and-configure/package.json b/exercises/01.fundamentals/01.problem.install-and-configure/package.json
new file mode 100644
index 0000000..a00a70d
--- /dev/null
+++ b/exercises/01.fundamentals/01.problem.install-and-configure/package.json
@@ -0,0 +1,3 @@
+{
+ "name": "exercises_01.fundamentals_01.problem.install-and-configure"
+}
diff --git a/exercises/01.basics/01.problem.install-and-configure/tsconfig.json b/exercises/01.fundamentals/01.problem.install-and-configure/tsconfig.json
similarity index 100%
rename from exercises/01.basics/01.problem.install-and-configure/tsconfig.json
rename to exercises/01.fundamentals/01.problem.install-and-configure/tsconfig.json
diff --git a/exercises/01.basics/01.solution.install-and-configure/README.mdx b/exercises/01.fundamentals/01.solution.install-and-configure/README.mdx
similarity index 100%
rename from exercises/01.basics/01.solution.install-and-configure/README.mdx
rename to exercises/01.fundamentals/01.solution.install-and-configure/README.mdx
diff --git a/exercises/01.basics/01.solution.install-and-configure/package.json b/exercises/01.fundamentals/01.solution.install-and-configure/package.json
similarity index 61%
rename from exercises/01.basics/01.solution.install-and-configure/package.json
rename to exercises/01.fundamentals/01.solution.install-and-configure/package.json
index 5fa9319..1c8fe4d 100644
--- a/exercises/01.basics/01.solution.install-and-configure/package.json
+++ b/exercises/01.fundamentals/01.solution.install-and-configure/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_01.basics_01.solution.install-and-configure",
+ "name": "exercises_01.fundamentals_01.solution.install-and-configure",
"scripts": {
"test:e2e": "playwright test"
},
diff --git a/exercises/01.basics/01.solution.install-and-configure/playwright.config.ts b/exercises/01.fundamentals/01.solution.install-and-configure/playwright.config.ts
similarity index 100%
rename from exercises/01.basics/01.solution.install-and-configure/playwright.config.ts
rename to exercises/01.fundamentals/01.solution.install-and-configure/playwright.config.ts
diff --git a/exercises/01.basics/01.solution.install-and-configure/tests/epicweb.test.ts b/exercises/01.fundamentals/01.solution.install-and-configure/tests/epicweb.test.ts
similarity index 100%
rename from exercises/01.basics/01.solution.install-and-configure/tests/epicweb.test.ts
rename to exercises/01.fundamentals/01.solution.install-and-configure/tests/epicweb.test.ts
diff --git a/exercises/01.basics/01.solution.install-and-configure/tsconfig.json b/exercises/01.fundamentals/01.solution.install-and-configure/tsconfig.json
similarity index 100%
rename from exercises/01.basics/01.solution.install-and-configure/tsconfig.json
rename to exercises/01.fundamentals/01.solution.install-and-configure/tsconfig.json
diff --git a/exercises/01.basics/02.problem.running-the-app/.env b/exercises/01.fundamentals/02.problem.running-the-app/.env
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.env
rename to exercises/01.fundamentals/02.problem.running-the-app/.env
diff --git a/exercises/01.basics/02.problem.running-the-app/.env.example b/exercises/01.fundamentals/02.problem.running-the-app/.env.example
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.env.example
rename to exercises/01.fundamentals/02.problem.running-the-app/.env.example
diff --git a/exercises/01.basics/02.problem.running-the-app/.github/PULL_REQUEST_TEMPLATE.md b/exercises/01.fundamentals/02.problem.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/01.fundamentals/02.problem.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/01.basics/02.problem.running-the-app/.github/workflows/deploy.yml b/exercises/01.fundamentals/02.problem.running-the-app/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.github/workflows/deploy.yml
rename to exercises/01.fundamentals/02.problem.running-the-app/.github/workflows/deploy.yml
diff --git a/exercises/01.basics/02.problem.running-the-app/.gitignore b/exercises/01.fundamentals/02.problem.running-the-app/.gitignore
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.gitignore
rename to exercises/01.fundamentals/02.problem.running-the-app/.gitignore
diff --git a/exercises/01.basics/02.problem.running-the-app/.npmrc b/exercises/01.fundamentals/02.problem.running-the-app/.npmrc
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.npmrc
rename to exercises/01.fundamentals/02.problem.running-the-app/.npmrc
diff --git a/exercises/01.basics/02.problem.running-the-app/.prettierignore b/exercises/01.fundamentals/02.problem.running-the-app/.prettierignore
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.prettierignore
rename to exercises/01.fundamentals/02.problem.running-the-app/.prettierignore
diff --git a/exercises/01.basics/02.problem.running-the-app/.vscode/extensions.json b/exercises/01.fundamentals/02.problem.running-the-app/.vscode/extensions.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.vscode/extensions.json
rename to exercises/01.fundamentals/02.problem.running-the-app/.vscode/extensions.json
diff --git a/exercises/01.basics/02.problem.running-the-app/.vscode/remix.code-snippets b/exercises/01.fundamentals/02.problem.running-the-app/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.vscode/remix.code-snippets
rename to exercises/01.fundamentals/02.problem.running-the-app/.vscode/remix.code-snippets
diff --git a/exercises/01.basics/02.problem.running-the-app/.vscode/settings.json b/exercises/01.fundamentals/02.problem.running-the-app/.vscode/settings.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/.vscode/settings.json
rename to exercises/01.fundamentals/02.problem.running-the-app/.vscode/settings.json
diff --git a/exercises/01.basics/02.problem.running-the-app/README.mdx b/exercises/01.fundamentals/02.problem.running-the-app/README.mdx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/README.mdx
rename to exercises/01.fundamentals/02.problem.running-the-app/README.mdx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/assets/favicons/apple-touch-icon.png b/exercises/01.fundamentals/02.problem.running-the-app/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/assets/favicons/apple-touch-icon.png
rename to exercises/01.fundamentals/02.problem.running-the-app/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/01.basics/02.problem.running-the-app/app/assets/favicons/favicon.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/assets/favicons/favicon.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/assets/favicons/favicon.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/error-boundary.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/error-boundary.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/error-boundary.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/floating-toolbar.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/floating-toolbar.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/floating-toolbar.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/forms.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/forms.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/forms.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/forms.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/progress-bar.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/progress-bar.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/progress-bar.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/search-bar.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/search-bar.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/search-bar.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/search-bar.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/spacer.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/spacer.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/spacer.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/spacer.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/toaster.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/toaster.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/toaster.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/toaster.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/README.md b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/README.md
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/README.md
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/README.md
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/button.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/button.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/button.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/button.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/checkbox.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/checkbox.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/checkbox.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/dropdown-menu.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/dropdown-menu.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/icon.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/icon.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/icon.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/input-otp.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/input-otp.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/input-otp.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/input.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/input.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/input.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/input.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/label.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/label.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/label.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/label.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/sonner.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/sonner.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/sonner.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/status-button.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/status-button.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/status-button.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/textarea.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/textarea.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/textarea.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/ui/tooltip.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/ui/tooltip.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/ui/tooltip.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/components/user-dropdown.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/components/user-dropdown.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/components/user-dropdown.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/entry.client.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/entry.client.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/entry.client.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/entry.client.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/entry.server.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/entry.server.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/entry.server.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/entry.server.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/root.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/root.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/root.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/root.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/$.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/$.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/$.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/$.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth_.$provider.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/auth_.$provider.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/forgot-password.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/forgot-password.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/login.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/login.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/login.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/login.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/login.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/login.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/logout.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/logout.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/logout.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/reset-password.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/reset-password.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/reset-password.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/reset-password.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/signup.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/signup.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/signup.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/verify.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/verify.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/verify.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/verify.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/verify.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/verify.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/authentication.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/registration.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/about.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/about.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/about.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/index.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/index.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/index.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/docker.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/docker.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/eslint.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/eslint.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/faker.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/faker.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/fly.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/fly.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/github.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/github.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/logos.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/logos.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/msw.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/msw.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/playwright.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/playwright.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/prettier.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/prettier.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/prisma.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/prisma.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/radix.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/radix.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/react-email.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/react-email.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/remix.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/remix.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/resend.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/resend.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/sentry.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/sentry.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/sqlite.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/stars.jpg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/stars.jpg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/tailwind.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/testing-library.png b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/testing-library.png
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/typescript.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/typescript.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/vitest.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/vitest.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/zod.svg b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/logos/zod.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/privacy.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/privacy.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/support.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/support.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/support.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/tos.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_marketing+/tos.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_marketing+/tos.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_seo+/robots[.]txt.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_seo+/robots[.]txt.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/_seo+/sitemap[.]xml.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/me.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/me.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/me.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/me.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/resources+/download-user-data.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/resources+/download-user-data.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/resources+/healthcheck.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/resources+/healthcheck.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/resources+/images.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/resources+/images.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/images.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/resources+/theme-switch.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/resources+/theme-switch.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.change-email.server.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.change-email.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.change-email.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.connections.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.connections.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.index.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.index.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.index.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.passkeys.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.passkeys.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.password.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.password.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.password.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.password_.create.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.password_.create.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.photo.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.photo.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.index.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username.test.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username.test.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username.test.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.index.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.new.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/$username_+/notes.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/routes/users+/index.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/routes/users+/index.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/routes/users+/index.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/styles/tailwind.css b/exercises/01.fundamentals/02.problem.running-the-app/app/styles/tailwind.css
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/styles/tailwind.css
rename to exercises/01.fundamentals/02.problem.running-the-app/app/styles/tailwind.css
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/auth.server.test.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/auth.server.test.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/auth.server.test.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/auth.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/auth.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/auth.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/auth.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/cache.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/cache.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/cache.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/cache.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/client-hints.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/client-hints.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/client-hints.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/connections.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/connections.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/connections.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/connections.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/connections.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/connections.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/connections.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/connections.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/db.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/db.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/db.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/db.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/email.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/email.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/email.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/email.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/env.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/env.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/env.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/env.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/headers.server.test.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/headers.server.test.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/headers.server.test.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/headers.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/headers.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/headers.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/headers.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/honeypot.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/honeypot.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/honeypot.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/litefs.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/litefs.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/litefs.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/misc.error-message.test.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/misc.error-message.test.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.error-message.test.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/misc.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/misc.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/misc.use-double-check.test.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/misc.use-double-check.test.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/monitoring.client.tsx b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/monitoring.client.tsx
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/monitoring.client.tsx
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/nonce-provider.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/nonce-provider.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/nonce-provider.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/permissions.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/permissions.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/permissions.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/providers/constants.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/providers/constants.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/constants.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/providers/github.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/providers/github.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/github.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/providers/provider.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/providers/provider.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/providers/provider.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/redirect-cookie.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/redirect-cookie.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/redirect-cookie.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/request-info.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/request-info.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/request-info.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/request-info.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/session.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/session.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/session.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/session.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/storage.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/storage.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/storage.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/storage.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/theme.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/theme.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/theme.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/theme.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/timing.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/timing.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/timing.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/timing.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/toast.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/toast.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/toast.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/toast.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/totp.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/totp.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/totp.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/totp.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/user-validation.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/user-validation.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/user-validation.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/user-validation.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/user.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/user.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/user.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/user.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/app/utils/verification.server.ts b/exercises/01.fundamentals/02.problem.running-the-app/app/utils/verification.server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/app/utils/verification.server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/app/utils/verification.server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/components.json b/exercises/01.fundamentals/02.problem.running-the-app/components.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/components.json
rename to exercises/01.fundamentals/02.problem.running-the-app/components.json
diff --git a/exercises/01.basics/02.problem.running-the-app/eslint.config.js b/exercises/01.fundamentals/02.problem.running-the-app/eslint.config.js
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/eslint.config.js
rename to exercises/01.fundamentals/02.problem.running-the-app/eslint.config.js
diff --git a/exercises/01.basics/02.problem.running-the-app/fly.toml b/exercises/01.fundamentals/02.problem.running-the-app/fly.toml
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/fly.toml
rename to exercises/01.fundamentals/02.problem.running-the-app/fly.toml
diff --git a/exercises/01.basics/02.problem.running-the-app/index.js b/exercises/01.fundamentals/02.problem.running-the-app/index.js
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/index.js
rename to exercises/01.fundamentals/02.problem.running-the-app/index.js
diff --git a/exercises/01.basics/02.problem.running-the-app/other/Dockerfile b/exercises/01.fundamentals/02.problem.running-the-app/other/Dockerfile
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/Dockerfile
rename to exercises/01.fundamentals/02.problem.running-the-app/other/Dockerfile
diff --git a/exercises/01.basics/02.problem.running-the-app/other/Dockerfile.dockerignore b/exercises/01.fundamentals/02.problem.running-the-app/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/Dockerfile.dockerignore
rename to exercises/01.fundamentals/02.problem.running-the-app/other/Dockerfile.dockerignore
diff --git a/exercises/01.basics/02.problem.running-the-app/other/README.md b/exercises/01.fundamentals/02.problem.running-the-app/other/README.md
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/README.md
rename to exercises/01.fundamentals/02.problem.running-the-app/other/README.md
diff --git a/exercises/01.basics/02.problem.running-the-app/other/build-server.ts b/exercises/01.fundamentals/02.problem.running-the-app/other/build-server.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/build-server.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/other/build-server.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/other/litefs.yml b/exercises/01.fundamentals/02.problem.running-the-app/other/litefs.yml
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/litefs.yml
rename to exercises/01.fundamentals/02.problem.running-the-app/other/litefs.yml
diff --git a/exercises/01.basics/02.problem.running-the-app/other/sly/sly.json b/exercises/01.fundamentals/02.problem.running-the-app/other/sly/sly.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/sly/sly.json
rename to exercises/01.fundamentals/02.problem.running-the-app/other/sly/sly.json
diff --git a/exercises/01.basics/02.problem.running-the-app/other/sly/transform-icon.ts b/exercises/01.fundamentals/02.problem.running-the-app/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/sly/transform-icon.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/other/sly/transform-icon.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/README.md b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/README.md
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/README.md
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/README.md
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/arrow-left.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/arrow-left.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/arrow-left.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/arrow-right.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/arrow-right.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/arrow-right.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/avatar.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/avatar.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/avatar.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/camera.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/camera.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/camera.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/check.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/check.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/check.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/check.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/clock.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/clock.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/clock.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/cross-1.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/cross-1.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/cross-1.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/dots-horizontal.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/dots-horizontal.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/download.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/download.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/download.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/download.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/envelope-closed.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/envelope-closed.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/envelope-closed.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/exit.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/exit.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/exit.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/file-text.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/file-text.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/file-text.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/github-logo.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/github-logo.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/github-logo.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/laptop.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/laptop.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/laptop.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/link-2.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/link-2.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/link-2.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/lock-closed.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/lock-closed.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/lock-closed.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/lock-open-1.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/lock-open-1.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/lock-open-1.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/magnifying-glass.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/magnifying-glass.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/moon.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/moon.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/moon.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/passkey.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/passkey.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/passkey.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/pencil-1.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/pencil-1.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/pencil-1.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/pencil-2.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/pencil-2.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/pencil-2.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/plus.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/plus.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/plus.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/question-mark-circled.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/question-mark-circled.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/reset.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/reset.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/reset.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/sun.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/sun.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/sun.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/trash.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/trash.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/trash.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/other/svg-icons/update.svg b/exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/update.svg
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/other/svg-icons/update.svg
rename to exercises/01.fundamentals/02.problem.running-the-app/other/svg-icons/update.svg
diff --git a/exercises/01.basics/02.problem.running-the-app/package-lock.json b/exercises/01.fundamentals/02.problem.running-the-app/package-lock.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/package-lock.json
rename to exercises/01.fundamentals/02.problem.running-the-app/package-lock.json
diff --git a/exercises/01.basics/02.problem.running-the-app/package.json b/exercises/01.fundamentals/02.problem.running-the-app/package.json
similarity index 98%
rename from exercises/01.basics/02.problem.running-the-app/package.json
rename to exercises/01.fundamentals/02.problem.running-the-app/package.json
index 06a4d8b..2d5aeb0 100644
--- a/exercises/01.basics/02.problem.running-the-app/package.json
+++ b/exercises/01.fundamentals/02.problem.running-the-app/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_01.basics_02.problem.running-the-app",
+ "name": "exercises_01.fundamentals_02.problem.running-the-app",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/01.basics/02.problem.running-the-app/playwright.config.ts b/exercises/01.fundamentals/02.problem.running-the-app/playwright.config.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/playwright.config.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/playwright.config.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/prisma/migrations/20250221233640_init/migration.sql b/exercises/01.fundamentals/02.problem.running-the-app/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/01.fundamentals/02.problem.running-the-app/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/01.basics/02.problem.running-the-app/prisma/migrations/migration_lock.toml b/exercises/01.fundamentals/02.problem.running-the-app/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/prisma/migrations/migration_lock.toml
rename to exercises/01.fundamentals/02.problem.running-the-app/prisma/migrations/migration_lock.toml
diff --git a/exercises/01.basics/02.problem.running-the-app/prisma/schema.prisma b/exercises/01.fundamentals/02.problem.running-the-app/prisma/schema.prisma
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/prisma/schema.prisma
rename to exercises/01.fundamentals/02.problem.running-the-app/prisma/schema.prisma
diff --git a/exercises/01.basics/02.problem.running-the-app/prisma/seed.ts b/exercises/01.fundamentals/02.problem.running-the-app/prisma/seed.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/prisma/seed.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/prisma/seed.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/prisma/sql/searchUsers.sql b/exercises/01.fundamentals/02.problem.running-the-app/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/prisma/sql/searchUsers.sql
rename to exercises/01.fundamentals/02.problem.running-the-app/prisma/sql/searchUsers.sql
diff --git a/exercises/01.basics/02.problem.running-the-app/public/favicon.ico b/exercises/01.fundamentals/02.problem.running-the-app/public/favicon.ico
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/favicon.ico
rename to exercises/01.fundamentals/02.problem.running-the-app/public/favicon.ico
diff --git a/exercises/01.basics/02.problem.running-the-app/public/favicons/README.md b/exercises/01.fundamentals/02.problem.running-the-app/public/favicons/README.md
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/favicons/README.md
rename to exercises/01.fundamentals/02.problem.running-the-app/public/favicons/README.md
diff --git a/exercises/01.basics/02.problem.running-the-app/public/favicons/android-chrome-192x192.png b/exercises/01.fundamentals/02.problem.running-the-app/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/favicons/android-chrome-192x192.png
rename to exercises/01.fundamentals/02.problem.running-the-app/public/favicons/android-chrome-192x192.png
diff --git a/exercises/01.basics/02.problem.running-the-app/public/favicons/android-chrome-512x512.png b/exercises/01.fundamentals/02.problem.running-the-app/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/favicons/android-chrome-512x512.png
rename to exercises/01.fundamentals/02.problem.running-the-app/public/favicons/android-chrome-512x512.png
diff --git a/exercises/01.basics/02.problem.running-the-app/public/img/user.png b/exercises/01.fundamentals/02.problem.running-the-app/public/img/user.png
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/img/user.png
rename to exercises/01.fundamentals/02.problem.running-the-app/public/img/user.png
diff --git a/exercises/01.basics/02.problem.running-the-app/public/site.webmanifest b/exercises/01.fundamentals/02.problem.running-the-app/public/site.webmanifest
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/public/site.webmanifest
rename to exercises/01.fundamentals/02.problem.running-the-app/public/site.webmanifest
diff --git a/exercises/01.basics/02.problem.running-the-app/react-router.config.ts b/exercises/01.fundamentals/02.problem.running-the-app/react-router.config.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/react-router.config.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/react-router.config.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/server/dev-server.js b/exercises/01.fundamentals/02.problem.running-the-app/server/dev-server.js
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/server/dev-server.js
rename to exercises/01.fundamentals/02.problem.running-the-app/server/dev-server.js
diff --git a/exercises/01.basics/02.problem.running-the-app/server/index.ts b/exercises/01.fundamentals/02.problem.running-the-app/server/index.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/server/index.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/server/index.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/server/utils/monitoring.ts b/exercises/01.fundamentals/02.problem.running-the-app/server/utils/monitoring.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/server/utils/monitoring.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/server/utils/monitoring.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/db-utils.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/db-utils.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/db-utils.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/db-utils.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/e2e/homepage.test.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/e2e/homepage.test.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/e2e/homepage.test.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/e2e/homepage.test.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/setup/custom-matchers.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/setup/custom-matchers.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/setup/custom-matchers.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/setup/db-setup.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/setup/db-setup.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/setup/db-setup.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/setup/global-setup.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/setup/global-setup.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/setup/global-setup.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/setup/setup-test-env.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/setup/setup-test-env.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/setup/setup-test-env.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tests/utils.ts b/exercises/01.fundamentals/02.problem.running-the-app/tests/utils.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tests/utils.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/tests/utils.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/tsconfig.json b/exercises/01.fundamentals/02.problem.running-the-app/tsconfig.json
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/tsconfig.json
rename to exercises/01.fundamentals/02.problem.running-the-app/tsconfig.json
diff --git a/exercises/01.basics/02.problem.running-the-app/types/deps.d.ts b/exercises/01.fundamentals/02.problem.running-the-app/types/deps.d.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/types/deps.d.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/types/deps.d.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/types/env.env.d.ts b/exercises/01.fundamentals/02.problem.running-the-app/types/env.env.d.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/types/env.env.d.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/types/env.env.d.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/types/icon-name.d.ts b/exercises/01.fundamentals/02.problem.running-the-app/types/icon-name.d.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/types/icon-name.d.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/types/icon-name.d.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/types/reset.d.ts b/exercises/01.fundamentals/02.problem.running-the-app/types/reset.d.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/types/reset.d.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/types/reset.d.ts
diff --git a/exercises/01.basics/02.problem.running-the-app/vite.config.ts b/exercises/01.fundamentals/02.problem.running-the-app/vite.config.ts
similarity index 100%
rename from exercises/01.basics/02.problem.running-the-app/vite.config.ts
rename to exercises/01.fundamentals/02.problem.running-the-app/vite.config.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/.env b/exercises/01.fundamentals/02.solution.running-the-app/.env
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.env
rename to exercises/01.fundamentals/02.solution.running-the-app/.env
diff --git a/exercises/01.basics/02.solution.running-the-app/.env.example b/exercises/01.fundamentals/02.solution.running-the-app/.env.example
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.env.example
rename to exercises/01.fundamentals/02.solution.running-the-app/.env.example
diff --git a/exercises/01.basics/02.solution.running-the-app/.github/PULL_REQUEST_TEMPLATE.md b/exercises/01.fundamentals/02.solution.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/01.fundamentals/02.solution.running-the-app/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/01.basics/02.solution.running-the-app/.github/workflows/deploy.yml b/exercises/01.fundamentals/02.solution.running-the-app/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.github/workflows/deploy.yml
rename to exercises/01.fundamentals/02.solution.running-the-app/.github/workflows/deploy.yml
diff --git a/exercises/01.basics/02.solution.running-the-app/.gitignore b/exercises/01.fundamentals/02.solution.running-the-app/.gitignore
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.gitignore
rename to exercises/01.fundamentals/02.solution.running-the-app/.gitignore
diff --git a/exercises/01.basics/02.solution.running-the-app/.npmrc b/exercises/01.fundamentals/02.solution.running-the-app/.npmrc
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.npmrc
rename to exercises/01.fundamentals/02.solution.running-the-app/.npmrc
diff --git a/exercises/01.basics/02.solution.running-the-app/.prettierignore b/exercises/01.fundamentals/02.solution.running-the-app/.prettierignore
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.prettierignore
rename to exercises/01.fundamentals/02.solution.running-the-app/.prettierignore
diff --git a/exercises/01.basics/02.solution.running-the-app/.vscode/extensions.json b/exercises/01.fundamentals/02.solution.running-the-app/.vscode/extensions.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.vscode/extensions.json
rename to exercises/01.fundamentals/02.solution.running-the-app/.vscode/extensions.json
diff --git a/exercises/01.basics/02.solution.running-the-app/.vscode/remix.code-snippets b/exercises/01.fundamentals/02.solution.running-the-app/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.vscode/remix.code-snippets
rename to exercises/01.fundamentals/02.solution.running-the-app/.vscode/remix.code-snippets
diff --git a/exercises/01.basics/02.solution.running-the-app/.vscode/settings.json b/exercises/01.fundamentals/02.solution.running-the-app/.vscode/settings.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/.vscode/settings.json
rename to exercises/01.fundamentals/02.solution.running-the-app/.vscode/settings.json
diff --git a/exercises/01.basics/02.solution.running-the-app/README.mdx b/exercises/01.fundamentals/02.solution.running-the-app/README.mdx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/README.mdx
rename to exercises/01.fundamentals/02.solution.running-the-app/README.mdx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/assets/favicons/apple-touch-icon.png b/exercises/01.fundamentals/02.solution.running-the-app/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/assets/favicons/apple-touch-icon.png
rename to exercises/01.fundamentals/02.solution.running-the-app/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/01.basics/02.solution.running-the-app/app/assets/favicons/favicon.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/assets/favicons/favicon.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/assets/favicons/favicon.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/error-boundary.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/error-boundary.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/error-boundary.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/floating-toolbar.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/floating-toolbar.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/floating-toolbar.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/forms.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/forms.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/forms.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/forms.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/progress-bar.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/progress-bar.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/progress-bar.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/search-bar.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/search-bar.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/search-bar.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/search-bar.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/spacer.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/spacer.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/spacer.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/spacer.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/toaster.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/toaster.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/toaster.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/toaster.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/README.md b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/README.md
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/README.md
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/README.md
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/button.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/button.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/button.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/button.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/checkbox.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/checkbox.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/checkbox.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/dropdown-menu.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/dropdown-menu.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/icon.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/icon.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/icon.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/input-otp.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/input-otp.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/input-otp.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/input.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/input.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/input.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/input.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/label.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/label.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/label.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/label.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/sonner.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/sonner.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/sonner.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/status-button.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/status-button.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/status-button.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/textarea.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/textarea.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/textarea.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/ui/tooltip.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/ui/tooltip.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/ui/tooltip.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/components/user-dropdown.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/components/user-dropdown.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/components/user-dropdown.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/entry.client.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/entry.client.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/entry.client.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/entry.client.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/entry.server.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/entry.server.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/entry.server.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/entry.server.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/root.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/root.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/root.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/root.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/$.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/$.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/$.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/$.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth_.$provider.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/auth_.$provider.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/forgot-password.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/forgot-password.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/login.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/login.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/login.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/login.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/login.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/login.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/logout.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/logout.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/logout.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/reset-password.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/reset-password.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/reset-password.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/reset-password.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/signup.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/signup.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/signup.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/verify.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/verify.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/verify.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/verify.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/verify.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/verify.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/authentication.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/registration.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/about.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/about.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/about.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/index.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/index.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/index.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/docker.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/docker.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/eslint.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/eslint.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/faker.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/faker.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/fly.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/fly.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/github.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/github.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/logos.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/logos.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/msw.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/msw.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/playwright.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/playwright.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/prettier.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/prettier.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/prisma.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/prisma.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/radix.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/radix.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/react-email.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/react-email.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/remix.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/remix.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/resend.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/resend.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/sentry.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/sentry.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/sqlite.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/stars.jpg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/stars.jpg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/tailwind.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/testing-library.png b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/testing-library.png
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/typescript.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/typescript.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/vitest.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/vitest.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/zod.svg b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/logos/zod.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/privacy.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/privacy.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/support.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/support.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/support.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/tos.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_marketing+/tos.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_marketing+/tos.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_seo+/robots[.]txt.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_seo+/robots[.]txt.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/_seo+/sitemap[.]xml.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/me.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/me.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/me.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/me.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/resources+/download-user-data.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/resources+/download-user-data.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/resources+/healthcheck.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/resources+/healthcheck.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/resources+/images.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/resources+/images.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/images.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/resources+/theme-switch.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/resources+/theme-switch.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.change-email.server.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.change-email.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.change-email.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.connections.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.connections.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.index.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.index.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.index.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.passkeys.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.passkeys.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.password.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.password.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.password.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.password_.create.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.password_.create.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.photo.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.photo.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.index.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username.test.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username.test.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username.test.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.index.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.new.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/$username_+/notes.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/routes/users+/index.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/routes/users+/index.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/routes/users+/index.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/styles/tailwind.css b/exercises/01.fundamentals/02.solution.running-the-app/app/styles/tailwind.css
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/styles/tailwind.css
rename to exercises/01.fundamentals/02.solution.running-the-app/app/styles/tailwind.css
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/auth.server.test.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/auth.server.test.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/auth.server.test.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/auth.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/auth.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/auth.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/auth.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/cache.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/cache.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/cache.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/cache.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/client-hints.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/client-hints.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/client-hints.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/connections.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/connections.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/connections.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/connections.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/connections.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/connections.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/connections.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/connections.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/db.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/db.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/db.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/db.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/email.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/email.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/email.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/email.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/env.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/env.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/env.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/env.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/headers.server.test.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/headers.server.test.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/headers.server.test.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/headers.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/headers.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/headers.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/headers.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/honeypot.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/honeypot.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/honeypot.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/litefs.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/litefs.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/litefs.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/misc.error-message.test.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/misc.error-message.test.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.error-message.test.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/misc.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/misc.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/misc.use-double-check.test.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/misc.use-double-check.test.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/monitoring.client.tsx b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/monitoring.client.tsx
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/monitoring.client.tsx
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/nonce-provider.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/nonce-provider.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/nonce-provider.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/permissions.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/permissions.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/permissions.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/providers/constants.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/providers/constants.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/constants.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/providers/github.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/providers/github.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/github.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/providers/provider.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/providers/provider.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/providers/provider.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/redirect-cookie.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/redirect-cookie.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/redirect-cookie.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/request-info.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/request-info.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/request-info.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/request-info.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/session.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/session.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/session.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/session.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/storage.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/storage.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/storage.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/storage.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/theme.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/theme.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/theme.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/theme.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/timing.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/timing.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/timing.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/timing.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/toast.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/toast.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/toast.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/toast.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/totp.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/totp.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/totp.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/totp.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/user-validation.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/user-validation.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/user-validation.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/user-validation.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/user.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/user.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/user.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/user.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/app/utils/verification.server.ts b/exercises/01.fundamentals/02.solution.running-the-app/app/utils/verification.server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/app/utils/verification.server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/app/utils/verification.server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/components.json b/exercises/01.fundamentals/02.solution.running-the-app/components.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/components.json
rename to exercises/01.fundamentals/02.solution.running-the-app/components.json
diff --git a/exercises/01.basics/02.solution.running-the-app/eslint.config.js b/exercises/01.fundamentals/02.solution.running-the-app/eslint.config.js
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/eslint.config.js
rename to exercises/01.fundamentals/02.solution.running-the-app/eslint.config.js
diff --git a/exercises/01.basics/02.solution.running-the-app/fly.toml b/exercises/01.fundamentals/02.solution.running-the-app/fly.toml
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/fly.toml
rename to exercises/01.fundamentals/02.solution.running-the-app/fly.toml
diff --git a/exercises/01.basics/02.solution.running-the-app/index.js b/exercises/01.fundamentals/02.solution.running-the-app/index.js
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/index.js
rename to exercises/01.fundamentals/02.solution.running-the-app/index.js
diff --git a/exercises/01.basics/02.solution.running-the-app/other/Dockerfile b/exercises/01.fundamentals/02.solution.running-the-app/other/Dockerfile
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/Dockerfile
rename to exercises/01.fundamentals/02.solution.running-the-app/other/Dockerfile
diff --git a/exercises/01.basics/02.solution.running-the-app/other/Dockerfile.dockerignore b/exercises/01.fundamentals/02.solution.running-the-app/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/Dockerfile.dockerignore
rename to exercises/01.fundamentals/02.solution.running-the-app/other/Dockerfile.dockerignore
diff --git a/exercises/01.basics/02.solution.running-the-app/other/README.md b/exercises/01.fundamentals/02.solution.running-the-app/other/README.md
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/README.md
rename to exercises/01.fundamentals/02.solution.running-the-app/other/README.md
diff --git a/exercises/01.basics/02.solution.running-the-app/other/build-server.ts b/exercises/01.fundamentals/02.solution.running-the-app/other/build-server.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/build-server.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/other/build-server.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/other/litefs.yml b/exercises/01.fundamentals/02.solution.running-the-app/other/litefs.yml
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/litefs.yml
rename to exercises/01.fundamentals/02.solution.running-the-app/other/litefs.yml
diff --git a/exercises/01.basics/02.solution.running-the-app/other/sly/sly.json b/exercises/01.fundamentals/02.solution.running-the-app/other/sly/sly.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/sly/sly.json
rename to exercises/01.fundamentals/02.solution.running-the-app/other/sly/sly.json
diff --git a/exercises/01.basics/02.solution.running-the-app/other/sly/transform-icon.ts b/exercises/01.fundamentals/02.solution.running-the-app/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/sly/transform-icon.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/other/sly/transform-icon.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/README.md b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/README.md
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/README.md
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/README.md
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/arrow-left.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/arrow-left.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/arrow-left.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/arrow-right.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/arrow-right.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/arrow-right.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/avatar.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/avatar.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/avatar.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/camera.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/camera.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/camera.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/check.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/check.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/check.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/check.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/clock.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/clock.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/clock.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/cross-1.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/cross-1.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/cross-1.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/dots-horizontal.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/dots-horizontal.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/download.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/download.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/download.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/download.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/envelope-closed.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/envelope-closed.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/envelope-closed.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/exit.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/exit.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/exit.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/file-text.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/file-text.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/file-text.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/github-logo.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/github-logo.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/github-logo.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/laptop.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/laptop.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/laptop.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/link-2.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/link-2.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/link-2.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/lock-closed.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/lock-closed.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/lock-closed.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/lock-open-1.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/lock-open-1.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/lock-open-1.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/magnifying-glass.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/magnifying-glass.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/moon.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/moon.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/moon.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/passkey.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/passkey.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/passkey.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/pencil-1.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/pencil-1.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/pencil-1.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/pencil-2.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/pencil-2.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/pencil-2.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/plus.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/plus.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/plus.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/question-mark-circled.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/question-mark-circled.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/reset.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/reset.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/reset.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/sun.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/sun.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/sun.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/trash.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/trash.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/trash.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/other/svg-icons/update.svg b/exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/update.svg
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/other/svg-icons/update.svg
rename to exercises/01.fundamentals/02.solution.running-the-app/other/svg-icons/update.svg
diff --git a/exercises/01.basics/02.solution.running-the-app/package-lock.json b/exercises/01.fundamentals/02.solution.running-the-app/package-lock.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/package-lock.json
rename to exercises/01.fundamentals/02.solution.running-the-app/package-lock.json
diff --git a/exercises/01.basics/02.solution.running-the-app/package.json b/exercises/01.fundamentals/02.solution.running-the-app/package.json
similarity index 98%
rename from exercises/01.basics/02.solution.running-the-app/package.json
rename to exercises/01.fundamentals/02.solution.running-the-app/package.json
index 538da31..d8ff21e 100644
--- a/exercises/01.basics/02.solution.running-the-app/package.json
+++ b/exercises/01.fundamentals/02.solution.running-the-app/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_01.basics_02.solution.running-the-app",
+ "name": "exercises_01.fundamentals_02.solution.running-the-app",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/01.basics/02.solution.running-the-app/playwright.config.ts b/exercises/01.fundamentals/02.solution.running-the-app/playwright.config.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/playwright.config.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/playwright.config.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/prisma/migrations/20250221233640_init/migration.sql b/exercises/01.fundamentals/02.solution.running-the-app/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/01.fundamentals/02.solution.running-the-app/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/01.basics/02.solution.running-the-app/prisma/migrations/migration_lock.toml b/exercises/01.fundamentals/02.solution.running-the-app/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/prisma/migrations/migration_lock.toml
rename to exercises/01.fundamentals/02.solution.running-the-app/prisma/migrations/migration_lock.toml
diff --git a/exercises/01.basics/02.solution.running-the-app/prisma/schema.prisma b/exercises/01.fundamentals/02.solution.running-the-app/prisma/schema.prisma
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/prisma/schema.prisma
rename to exercises/01.fundamentals/02.solution.running-the-app/prisma/schema.prisma
diff --git a/exercises/01.basics/02.solution.running-the-app/prisma/seed.ts b/exercises/01.fundamentals/02.solution.running-the-app/prisma/seed.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/prisma/seed.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/prisma/seed.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/prisma/sql/searchUsers.sql b/exercises/01.fundamentals/02.solution.running-the-app/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/prisma/sql/searchUsers.sql
rename to exercises/01.fundamentals/02.solution.running-the-app/prisma/sql/searchUsers.sql
diff --git a/exercises/01.basics/02.solution.running-the-app/public/favicon.ico b/exercises/01.fundamentals/02.solution.running-the-app/public/favicon.ico
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/favicon.ico
rename to exercises/01.fundamentals/02.solution.running-the-app/public/favicon.ico
diff --git a/exercises/01.basics/02.solution.running-the-app/public/favicons/README.md b/exercises/01.fundamentals/02.solution.running-the-app/public/favicons/README.md
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/favicons/README.md
rename to exercises/01.fundamentals/02.solution.running-the-app/public/favicons/README.md
diff --git a/exercises/01.basics/02.solution.running-the-app/public/favicons/android-chrome-192x192.png b/exercises/01.fundamentals/02.solution.running-the-app/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/favicons/android-chrome-192x192.png
rename to exercises/01.fundamentals/02.solution.running-the-app/public/favicons/android-chrome-192x192.png
diff --git a/exercises/01.basics/02.solution.running-the-app/public/favicons/android-chrome-512x512.png b/exercises/01.fundamentals/02.solution.running-the-app/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/favicons/android-chrome-512x512.png
rename to exercises/01.fundamentals/02.solution.running-the-app/public/favicons/android-chrome-512x512.png
diff --git a/exercises/01.basics/02.solution.running-the-app/public/img/user.png b/exercises/01.fundamentals/02.solution.running-the-app/public/img/user.png
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/img/user.png
rename to exercises/01.fundamentals/02.solution.running-the-app/public/img/user.png
diff --git a/exercises/01.basics/02.solution.running-the-app/public/site.webmanifest b/exercises/01.fundamentals/02.solution.running-the-app/public/site.webmanifest
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/public/site.webmanifest
rename to exercises/01.fundamentals/02.solution.running-the-app/public/site.webmanifest
diff --git a/exercises/01.basics/02.solution.running-the-app/react-router.config.ts b/exercises/01.fundamentals/02.solution.running-the-app/react-router.config.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/react-router.config.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/react-router.config.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/server/dev-server.js b/exercises/01.fundamentals/02.solution.running-the-app/server/dev-server.js
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/server/dev-server.js
rename to exercises/01.fundamentals/02.solution.running-the-app/server/dev-server.js
diff --git a/exercises/01.basics/02.solution.running-the-app/server/index.ts b/exercises/01.fundamentals/02.solution.running-the-app/server/index.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/server/index.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/server/index.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/server/utils/monitoring.ts b/exercises/01.fundamentals/02.solution.running-the-app/server/utils/monitoring.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/server/utils/monitoring.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/server/utils/monitoring.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/db-utils.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/db-utils.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/db-utils.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/db-utils.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/e2e/homepage.test.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/e2e/homepage.test.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/e2e/homepage.test.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/e2e/homepage.test.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/setup/custom-matchers.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/setup/custom-matchers.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/setup/custom-matchers.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/setup/db-setup.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/setup/db-setup.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/setup/db-setup.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/setup/global-setup.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/setup/global-setup.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/setup/global-setup.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/setup/setup-test-env.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/setup/setup-test-env.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/setup/setup-test-env.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tests/utils.ts b/exercises/01.fundamentals/02.solution.running-the-app/tests/utils.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tests/utils.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/tests/utils.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/tsconfig.json b/exercises/01.fundamentals/02.solution.running-the-app/tsconfig.json
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/tsconfig.json
rename to exercises/01.fundamentals/02.solution.running-the-app/tsconfig.json
diff --git a/exercises/01.basics/02.solution.running-the-app/types/deps.d.ts b/exercises/01.fundamentals/02.solution.running-the-app/types/deps.d.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/types/deps.d.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/types/deps.d.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/types/env.env.d.ts b/exercises/01.fundamentals/02.solution.running-the-app/types/env.env.d.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/types/env.env.d.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/types/env.env.d.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/types/icon-name.d.ts b/exercises/01.fundamentals/02.solution.running-the-app/types/icon-name.d.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/types/icon-name.d.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/types/icon-name.d.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/types/reset.d.ts b/exercises/01.fundamentals/02.solution.running-the-app/types/reset.d.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/types/reset.d.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/types/reset.d.ts
diff --git a/exercises/01.basics/02.solution.running-the-app/vite.config.ts b/exercises/01.fundamentals/02.solution.running-the-app/vite.config.ts
similarity index 100%
rename from exercises/01.basics/02.solution.running-the-app/vite.config.ts
rename to exercises/01.fundamentals/02.solution.running-the-app/vite.config.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.env b/exercises/01.fundamentals/03.problem.custom-fixtures/.env
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.env
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.env
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.env.example b/exercises/01.fundamentals/03.problem.custom-fixtures/.env.example
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.env.example
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.env.example
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md b/exercises/01.fundamentals/03.problem.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.github/workflows/deploy.yml b/exercises/01.fundamentals/03.problem.custom-fixtures/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.github/workflows/deploy.yml
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.github/workflows/deploy.yml
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.gitignore b/exercises/01.fundamentals/03.problem.custom-fixtures/.gitignore
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.gitignore
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.gitignore
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.npmrc b/exercises/01.fundamentals/03.problem.custom-fixtures/.npmrc
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.npmrc
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.npmrc
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.prettierignore b/exercises/01.fundamentals/03.problem.custom-fixtures/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.prettierignore
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.prettierignore
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.vscode/extensions.json b/exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.vscode/extensions.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/extensions.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.vscode/remix.code-snippets b/exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.vscode/remix.code-snippets
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/.vscode/settings.json b/exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/.vscode/settings.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/.vscode/settings.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/README.mdx b/exercises/01.fundamentals/03.problem.custom-fixtures/README.mdx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/README.mdx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/README.mdx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/assets/favicons/apple-touch-icon.png b/exercises/01.fundamentals/03.problem.custom-fixtures/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/assets/favicons/apple-touch-icon.png
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/assets/favicons/favicon.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/assets/favicons/favicon.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/error-boundary.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/error-boundary.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/floating-toolbar.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/floating-toolbar.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/forms.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/forms.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/forms.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/progress-bar.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/progress-bar.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/search-bar.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/search-bar.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/spacer.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/spacer.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/toaster.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/toaster.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/README.md b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/README.md
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/README.md
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/button.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/button.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/checkbox.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/checkbox.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/dropdown-menu.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/dropdown-menu.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/icon.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/icon.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/input-otp.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/input-otp.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/input.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/input.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/label.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/label.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/sonner.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/sonner.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/status-button.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/status-button.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/textarea.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/textarea.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/tooltip.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/ui/tooltip.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/components/user-dropdown.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/components/user-dropdown.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/entry.client.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/entry.client.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/entry.client.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/entry.server.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/entry.server.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/entry.server.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/root.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/root.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/root.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/$.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/$.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/$.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth_.$provider.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/forgot-password.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/forgot-password.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/login.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/login.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/login.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/login.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/logout.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/logout.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/reset-password.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/reset-password.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/reset-password.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/reset-password.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/signup.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/signup.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/verify.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/verify.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/verify.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/verify.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/about.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/about.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/index.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/index.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/docker.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/docker.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/eslint.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/faker.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/faker.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/fly.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/fly.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/github.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/github.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/logos.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/logos.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/msw.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/msw.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/playwright.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/prettier.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/prisma.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/radix.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/radix.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/react-email.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/remix.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/remix.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/resend.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/resend.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/sentry.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/stars.jpg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/testing-library.png b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/typescript.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/vitest.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/zod.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/logos/zod.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/privacy.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/privacy.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/support.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/support.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/tos.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_marketing+/tos.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_seo+/robots[.]txt.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/me.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/me.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/me.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/download-user-data.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/download-user-data.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/healthcheck.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/healthcheck.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/images.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/images.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/theme-switch.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/resources+/theme-switch.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.change-email.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.change-email.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.connections.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.connections.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.index.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.index.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.passkeys.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.password.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.password.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.password_.create.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.photo.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.photo.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username.test.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username.test.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username.test.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/$username_+/notes.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/index.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/routes/users+/index.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/styles/tailwind.css b/exercises/01.fundamentals/03.problem.custom-fixtures/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/styles/tailwind.css
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/auth.server.test.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/auth.server.test.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/auth.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/auth.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/cache.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/cache.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/client-hints.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/client-hints.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/connections.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/connections.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/connections.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/connections.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/db.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/db.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/email.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/email.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/env.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/env.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/headers.server.test.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/headers.server.test.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/headers.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/headers.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/honeypot.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/honeypot.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/litefs.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/litefs.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.error-message.test.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.error-message.test.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.use-double-check.test.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/misc.use-double-check.test.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/monitoring.client.tsx b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/monitoring.client.tsx
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/nonce-provider.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/nonce-provider.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/permissions.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/permissions.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/constants.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/constants.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/github.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/github.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/provider.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/providers/provider.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/redirect-cookie.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/redirect-cookie.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/request-info.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/request-info.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/session.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/session.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/storage.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/storage.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/theme.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/theme.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/timing.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/timing.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/toast.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/toast.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/totp.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/totp.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/user-validation.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/user-validation.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/user.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/user.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/user.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/app/utils/verification.server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/app/utils/verification.server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/components.json b/exercises/01.fundamentals/03.problem.custom-fixtures/components.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/components.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/components.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/eslint.config.js b/exercises/01.fundamentals/03.problem.custom-fixtures/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/eslint.config.js
rename to exercises/01.fundamentals/03.problem.custom-fixtures/eslint.config.js
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/fly.toml b/exercises/01.fundamentals/03.problem.custom-fixtures/fly.toml
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/fly.toml
rename to exercises/01.fundamentals/03.problem.custom-fixtures/fly.toml
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/index.js b/exercises/01.fundamentals/03.problem.custom-fixtures/index.js
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/index.js
rename to exercises/01.fundamentals/03.problem.custom-fixtures/index.js
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/Dockerfile b/exercises/01.fundamentals/03.problem.custom-fixtures/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/Dockerfile
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/Dockerfile
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/Dockerfile.dockerignore b/exercises/01.fundamentals/03.problem.custom-fixtures/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/Dockerfile.dockerignore
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/README.md b/exercises/01.fundamentals/03.problem.custom-fixtures/other/README.md
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/README.md
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/README.md
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/build-server.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/build-server.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/build-server.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/litefs.yml b/exercises/01.fundamentals/03.problem.custom-fixtures/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/litefs.yml
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/litefs.yml
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/sly/sly.json b/exercises/01.fundamentals/03.problem.custom-fixtures/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/sly/sly.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/sly/sly.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/sly/transform-icon.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/sly/transform-icon.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/README.md b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/README.md
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/arrow-left.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/arrow-left.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/arrow-right.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/arrow-right.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/avatar.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/avatar.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/camera.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/camera.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/check.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/check.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/clock.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/clock.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/cross-1.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/cross-1.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/dots-horizontal.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/dots-horizontal.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/download.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/download.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/envelope-closed.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/envelope-closed.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/exit.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/exit.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/file-text.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/file-text.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/github-logo.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/github-logo.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/laptop.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/laptop.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/link-2.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/link-2.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/lock-closed.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/lock-closed.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/lock-open-1.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/lock-open-1.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/magnifying-glass.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/magnifying-glass.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/moon.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/moon.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/passkey.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/passkey.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/pencil-1.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/pencil-1.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/pencil-2.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/pencil-2.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/plus.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/plus.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/question-mark-circled.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/question-mark-circled.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/reset.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/reset.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/sun.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/sun.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/trash.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/trash.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/update.svg b/exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/other/svg-icons/update.svg
rename to exercises/01.fundamentals/03.problem.custom-fixtures/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/package-lock.json b/exercises/01.fundamentals/03.problem.custom-fixtures/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/package-lock.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/package-lock.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/package.json b/exercises/01.fundamentals/03.problem.custom-fixtures/package.json
similarity index 98%
rename from exercises/02.test-setup/01.problem.custom-fixtures/package.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/package.json
index a150022..6b7f083 100644
--- a/exercises/02.test-setup/01.problem.custom-fixtures/package.json
+++ b/exercises/01.fundamentals/03.problem.custom-fixtures/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_01.problem.custom-fixtures",
+ "name": "exercises_01.fundamentals_03.problem.custom-fixtures",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/playwright.config.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/playwright.config.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/playwright.config.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql b/exercises/01.fundamentals/03.problem.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/01.fundamentals/03.problem.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/prisma/migrations/migration_lock.toml b/exercises/01.fundamentals/03.problem.custom-fixtures/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/prisma/migrations/migration_lock.toml
rename to exercises/01.fundamentals/03.problem.custom-fixtures/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/prisma/schema.prisma b/exercises/01.fundamentals/03.problem.custom-fixtures/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/prisma/schema.prisma
rename to exercises/01.fundamentals/03.problem.custom-fixtures/prisma/schema.prisma
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/prisma/seed.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/prisma/seed.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/prisma/seed.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/prisma/sql/searchUsers.sql b/exercises/01.fundamentals/03.problem.custom-fixtures/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/prisma/sql/searchUsers.sql
rename to exercises/01.fundamentals/03.problem.custom-fixtures/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/favicon.ico b/exercises/01.fundamentals/03.problem.custom-fixtures/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/favicon.ico
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/favicon.ico
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/README.md b/exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/README.md
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/README.md
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/android-chrome-192x192.png b/exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/android-chrome-192x192.png
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/android-chrome-512x512.png b/exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/favicons/android-chrome-512x512.png
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/img/user.png b/exercises/01.fundamentals/03.problem.custom-fixtures/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/img/user.png
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/img/user.png
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/public/site.webmanifest b/exercises/01.fundamentals/03.problem.custom-fixtures/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/public/site.webmanifest
rename to exercises/01.fundamentals/03.problem.custom-fixtures/public/site.webmanifest
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/react-router.config.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/react-router.config.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/react-router.config.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/server/dev-server.js b/exercises/01.fundamentals/03.problem.custom-fixtures/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/server/dev-server.js
rename to exercises/01.fundamentals/03.problem.custom-fixtures/server/dev-server.js
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/server/index.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/server/index.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/server/index.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/server/utils/monitoring.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/server/utils/monitoring.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/db-utils.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/db-utils.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/db-utils.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/e2e/homepage.test.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/e2e/homepage.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/e2e/homepage.test.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/e2e/homepage.test.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/custom-matchers.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/custom-matchers.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/db-setup.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/db-setup.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/global-setup.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/global-setup.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/setup-test-env.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/setup/setup-test-env.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/test-extend.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/test-extend.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/test-extend.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tests/utils.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tests/utils.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tests/utils.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/tsconfig.json b/exercises/01.fundamentals/03.problem.custom-fixtures/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/tsconfig.json
rename to exercises/01.fundamentals/03.problem.custom-fixtures/tsconfig.json
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/types/deps.d.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/types/deps.d.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/types/deps.d.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/types/env.env.d.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/types/env.env.d.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/types/env.env.d.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/types/icon-name.d.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/types/icon-name.d.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/types/reset.d.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/types/reset.d.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/types/reset.d.ts
diff --git a/exercises/02.test-setup/01.problem.custom-fixtures/vite.config.ts b/exercises/01.fundamentals/03.problem.custom-fixtures/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.problem.custom-fixtures/vite.config.ts
rename to exercises/01.fundamentals/03.problem.custom-fixtures/vite.config.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.env b/exercises/01.fundamentals/03.solution.custom-fixtures/.env
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.env
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.env
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.env.example b/exercises/01.fundamentals/03.solution.custom-fixtures/.env.example
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.env.example
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.env.example
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md b/exercises/01.fundamentals/03.solution.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.github/workflows/deploy.yml b/exercises/01.fundamentals/03.solution.custom-fixtures/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.github/workflows/deploy.yml
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.github/workflows/deploy.yml
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.gitignore b/exercises/01.fundamentals/03.solution.custom-fixtures/.gitignore
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.gitignore
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.gitignore
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.npmrc b/exercises/01.fundamentals/03.solution.custom-fixtures/.npmrc
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.npmrc
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.npmrc
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.prettierignore b/exercises/01.fundamentals/03.solution.custom-fixtures/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.prettierignore
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.prettierignore
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.vscode/extensions.json b/exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.vscode/extensions.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/extensions.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.vscode/remix.code-snippets b/exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.vscode/remix.code-snippets
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/.vscode/settings.json b/exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/.vscode/settings.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/.vscode/settings.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/README.mdx b/exercises/01.fundamentals/03.solution.custom-fixtures/README.mdx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/README.mdx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/README.mdx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/assets/favicons/apple-touch-icon.png b/exercises/01.fundamentals/03.solution.custom-fixtures/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/assets/favicons/apple-touch-icon.png
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/assets/favicons/favicon.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/assets/favicons/favicon.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/error-boundary.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/error-boundary.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/floating-toolbar.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/floating-toolbar.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/forms.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/forms.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/forms.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/progress-bar.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/progress-bar.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/search-bar.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/search-bar.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/spacer.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/spacer.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/toaster.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/toaster.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/README.md b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/README.md
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/README.md
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/button.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/button.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/checkbox.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/checkbox.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/dropdown-menu.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/dropdown-menu.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/icon.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/icon.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/input-otp.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/input-otp.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/input.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/input.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/label.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/label.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/sonner.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/sonner.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/status-button.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/status-button.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/textarea.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/textarea.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/tooltip.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/ui/tooltip.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/components/user-dropdown.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/components/user-dropdown.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/entry.client.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/entry.client.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/entry.client.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/entry.server.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/entry.server.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/entry.server.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/root.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/root.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/root.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/$.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/$.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/$.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth_.$provider.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/forgot-password.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/forgot-password.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/login.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/login.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/login.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/login.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/logout.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/logout.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/reset-password.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/reset-password.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/reset-password.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/reset-password.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/signup.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/signup.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/verify.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/verify.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/verify.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/verify.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/about.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/about.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/index.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/index.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/docker.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/docker.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/eslint.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/faker.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/faker.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/fly.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/fly.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/github.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/github.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/logos.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/logos.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/msw.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/msw.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/playwright.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/prettier.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/prisma.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/radix.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/radix.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/react-email.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/remix.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/remix.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/resend.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/resend.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/sentry.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/stars.jpg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/testing-library.png b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/typescript.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/vitest.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/zod.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/logos/zod.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/privacy.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/privacy.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/support.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/support.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/tos.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_marketing+/tos.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_seo+/robots[.]txt.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/me.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/me.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/me.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/download-user-data.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/download-user-data.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/healthcheck.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/healthcheck.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/images.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/images.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/theme-switch.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/resources+/theme-switch.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.change-email.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.change-email.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.connections.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.connections.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.index.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.index.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.passkeys.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.password.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.password.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.password_.create.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.photo.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.photo.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username.test.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username.test.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username.test.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/$username_+/notes.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/index.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/routes/users+/index.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/styles/tailwind.css b/exercises/01.fundamentals/03.solution.custom-fixtures/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/styles/tailwind.css
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/auth.server.test.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/auth.server.test.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/auth.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/auth.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/cache.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/cache.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/client-hints.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/client-hints.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/connections.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/connections.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/connections.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/connections.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/db.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/db.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/email.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/email.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/env.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/env.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/headers.server.test.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/headers.server.test.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/headers.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/headers.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/honeypot.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/honeypot.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/litefs.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/litefs.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.error-message.test.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.error-message.test.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.use-double-check.test.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/misc.use-double-check.test.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/monitoring.client.tsx b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/monitoring.client.tsx
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/nonce-provider.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/nonce-provider.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/permissions.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/permissions.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/constants.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/constants.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/github.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/github.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/provider.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/providers/provider.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/redirect-cookie.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/redirect-cookie.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/request-info.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/request-info.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/session.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/session.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/storage.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/storage.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/theme.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/theme.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/timing.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/timing.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/toast.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/toast.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/totp.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/totp.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/user-validation.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/user-validation.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/user.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/user.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/user.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/app/utils/verification.server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/app/utils/verification.server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/components.json b/exercises/01.fundamentals/03.solution.custom-fixtures/components.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/components.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/components.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/eslint.config.js b/exercises/01.fundamentals/03.solution.custom-fixtures/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/eslint.config.js
rename to exercises/01.fundamentals/03.solution.custom-fixtures/eslint.config.js
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/fly.toml b/exercises/01.fundamentals/03.solution.custom-fixtures/fly.toml
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/fly.toml
rename to exercises/01.fundamentals/03.solution.custom-fixtures/fly.toml
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/index.js b/exercises/01.fundamentals/03.solution.custom-fixtures/index.js
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/index.js
rename to exercises/01.fundamentals/03.solution.custom-fixtures/index.js
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/Dockerfile b/exercises/01.fundamentals/03.solution.custom-fixtures/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/Dockerfile
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/Dockerfile
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/Dockerfile.dockerignore b/exercises/01.fundamentals/03.solution.custom-fixtures/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/Dockerfile.dockerignore
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/README.md b/exercises/01.fundamentals/03.solution.custom-fixtures/other/README.md
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/README.md
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/README.md
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/build-server.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/build-server.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/build-server.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/litefs.yml b/exercises/01.fundamentals/03.solution.custom-fixtures/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/litefs.yml
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/litefs.yml
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/sly/sly.json b/exercises/01.fundamentals/03.solution.custom-fixtures/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/sly/sly.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/sly/sly.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/sly/transform-icon.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/sly/transform-icon.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/README.md b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/README.md
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/arrow-left.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/arrow-left.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/arrow-right.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/arrow-right.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/avatar.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/avatar.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/camera.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/camera.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/check.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/check.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/clock.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/clock.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/cross-1.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/cross-1.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/dots-horizontal.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/dots-horizontal.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/download.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/download.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/envelope-closed.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/envelope-closed.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/exit.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/exit.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/file-text.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/file-text.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/github-logo.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/github-logo.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/laptop.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/laptop.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/link-2.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/link-2.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/lock-closed.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/lock-closed.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/lock-open-1.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/lock-open-1.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/magnifying-glass.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/magnifying-glass.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/moon.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/moon.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/passkey.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/passkey.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/pencil-1.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/pencil-1.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/pencil-2.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/pencil-2.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/plus.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/plus.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/question-mark-circled.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/question-mark-circled.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/reset.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/reset.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/sun.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/sun.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/trash.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/trash.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/update.svg b/exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/other/svg-icons/update.svg
rename to exercises/01.fundamentals/03.solution.custom-fixtures/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/package-lock.json b/exercises/01.fundamentals/03.solution.custom-fixtures/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/package-lock.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/package-lock.json
diff --git a/exercises/03.guides/01.problem.recording-interactions/package.json b/exercises/01.fundamentals/03.solution.custom-fixtures/package.json
similarity index 98%
rename from exercises/03.guides/01.problem.recording-interactions/package.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/package.json
index b5931c3..d86cd6b 100644
--- a/exercises/03.guides/01.problem.recording-interactions/package.json
+++ b/exercises/01.fundamentals/03.solution.custom-fixtures/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_03.guides_01.problem.recording-interactions",
+ "name": "exercises_01.fundamentals_03.solution.custom-fixtures",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/playwright.config.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/playwright.config.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/playwright.config.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql b/exercises/01.fundamentals/03.solution.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/01.fundamentals/03.solution.custom-fixtures/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/prisma/migrations/migration_lock.toml b/exercises/01.fundamentals/03.solution.custom-fixtures/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/prisma/migrations/migration_lock.toml
rename to exercises/01.fundamentals/03.solution.custom-fixtures/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/prisma/schema.prisma b/exercises/01.fundamentals/03.solution.custom-fixtures/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/prisma/schema.prisma
rename to exercises/01.fundamentals/03.solution.custom-fixtures/prisma/schema.prisma
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/prisma/seed.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/prisma/seed.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/prisma/seed.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/prisma/sql/searchUsers.sql b/exercises/01.fundamentals/03.solution.custom-fixtures/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/prisma/sql/searchUsers.sql
rename to exercises/01.fundamentals/03.solution.custom-fixtures/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/favicon.ico b/exercises/01.fundamentals/03.solution.custom-fixtures/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/favicon.ico
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/favicon.ico
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/README.md b/exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/README.md
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/README.md
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/android-chrome-192x192.png b/exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/android-chrome-192x192.png
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/android-chrome-512x512.png b/exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/favicons/android-chrome-512x512.png
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/img/user.png b/exercises/01.fundamentals/03.solution.custom-fixtures/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/img/user.png
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/img/user.png
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/public/site.webmanifest b/exercises/01.fundamentals/03.solution.custom-fixtures/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/public/site.webmanifest
rename to exercises/01.fundamentals/03.solution.custom-fixtures/public/site.webmanifest
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/react-router.config.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/react-router.config.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/react-router.config.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/server/dev-server.js b/exercises/01.fundamentals/03.solution.custom-fixtures/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/server/dev-server.js
rename to exercises/01.fundamentals/03.solution.custom-fixtures/server/dev-server.js
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/server/index.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/server/index.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/server/index.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/server/utils/monitoring.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/server/utils/monitoring.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/db-utils.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/db-utils.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/db-utils.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/e2e/homepage.test.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/e2e/homepage.test.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/e2e/homepage.test.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/e2e/homepage.test.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/custom-matchers.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/custom-matchers.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/db-setup.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/db-setup.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/global-setup.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/global-setup.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/setup-test-env.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/setup/setup-test-env.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/test-extend.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/test-extend.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/test-extend.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tests/utils.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tests/utils.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tests/utils.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/tsconfig.json b/exercises/01.fundamentals/03.solution.custom-fixtures/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/tsconfig.json
rename to exercises/01.fundamentals/03.solution.custom-fixtures/tsconfig.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/types/deps.d.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/types/deps.d.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/types/deps.d.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/types/env.env.d.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/types/env.env.d.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/types/env.env.d.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/types/icon-name.d.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/types/icon-name.d.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/types/reset.d.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/types/reset.d.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/types/reset.d.ts
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/vite.config.ts b/exercises/01.fundamentals/03.solution.custom-fixtures/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/01.solution.custom-fixtures/vite.config.ts
rename to exercises/01.fundamentals/03.solution.custom-fixtures/vite.config.ts
diff --git a/exercises/01.basics/FINISHED.mdx b/exercises/01.fundamentals/FINISHED.mdx
similarity index 95%
rename from exercises/01.basics/FINISHED.mdx
rename to exercises/01.fundamentals/FINISHED.mdx
index c4d43d3..21bfc61 100644
--- a/exercises/01.basics/FINISHED.mdx
+++ b/exercises/01.fundamentals/FINISHED.mdx
@@ -1,4 +1,4 @@
-# Basics
+# Fundamentals
Congratulations, you've completed this exercise block! 🥳 Let's have a short rest and continue.
diff --git a/exercises/01.fundamentals/README.mdx b/exercises/01.fundamentals/README.mdx
new file mode 100644
index 0000000..2573e06
--- /dev/null
+++ b/exercises/01.fundamentals/README.mdx
@@ -0,0 +1 @@
+# Fundamentals
diff --git a/exercises/02.test-setup/03.problem.authentication/.env b/exercises/02.authentication/01.solution.basic/.env
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.env
rename to exercises/02.authentication/01.solution.basic/.env
diff --git a/exercises/02.test-setup/03.problem.authentication/.env.example b/exercises/02.authentication/01.solution.basic/.env.example
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.env.example
rename to exercises/02.authentication/01.solution.basic/.env.example
diff --git a/exercises/02.test-setup/03.problem.authentication/.gitignore b/exercises/02.authentication/01.solution.basic/.gitignore
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.gitignore
rename to exercises/02.authentication/01.solution.basic/.gitignore
diff --git a/exercises/02.test-setup/03.problem.authentication/.npmrc b/exercises/02.authentication/01.solution.basic/.npmrc
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.npmrc
rename to exercises/02.authentication/01.solution.basic/.npmrc
diff --git a/exercises/02.test-setup/03.problem.authentication/.prettierignore b/exercises/02.authentication/01.solution.basic/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.prettierignore
rename to exercises/02.authentication/01.solution.basic/.prettierignore
diff --git a/exercises/02.test-setup/03.problem.authentication/.vscode/extensions.json b/exercises/02.authentication/01.solution.basic/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.vscode/extensions.json
rename to exercises/02.authentication/01.solution.basic/.vscode/extensions.json
diff --git a/exercises/02.test-setup/03.problem.authentication/.vscode/remix.code-snippets b/exercises/02.authentication/01.solution.basic/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.vscode/remix.code-snippets
rename to exercises/02.authentication/01.solution.basic/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/03.problem.authentication/.vscode/settings.json b/exercises/02.authentication/01.solution.basic/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.vscode/settings.json
rename to exercises/02.authentication/01.solution.basic/.vscode/settings.json
diff --git a/exercises/02.authentication/01.solution.basic/README.mdx b/exercises/02.authentication/01.solution.basic/README.mdx
new file mode 100644
index 0000000..4113413
--- /dev/null
+++ b/exercises/02.authentication/01.solution.basic/README.mdx
@@ -0,0 +1,3 @@
+# Basic
+
+- Testing a basic (email+password) authentication.
diff --git a/exercises/02.test-setup/03.problem.authentication/app/assets/favicons/apple-touch-icon.png b/exercises/02.authentication/01.solution.basic/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/assets/favicons/apple-touch-icon.png
rename to exercises/02.authentication/01.solution.basic/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/03.problem.authentication/app/assets/favicons/favicon.svg b/exercises/02.authentication/01.solution.basic/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/assets/favicons/favicon.svg
rename to exercises/02.authentication/01.solution.basic/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/error-boundary.tsx b/exercises/02.authentication/01.solution.basic/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/error-boundary.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/floating-toolbar.tsx b/exercises/02.authentication/01.solution.basic/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/floating-toolbar.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/floating-toolbar.tsx
diff --git a/exercises/04.debugging/03.problem.live-debugging/app/components/forms.tsx b/exercises/02.authentication/01.solution.basic/app/components/forms.tsx
similarity index 98%
rename from exercises/04.debugging/03.problem.live-debugging/app/components/forms.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/forms.tsx
index abaabf7..8d3c72a 100644
--- a/exercises/04.debugging/03.problem.live-debugging/app/components/forms.tsx
+++ b/exercises/02.authentication/01.solution.basic/app/components/forms.tsx
@@ -24,7 +24,7 @@ export function ErrorList({
const errorsToRender = errors?.filter(Boolean)
if (!errorsToRender?.length) return null
return (
-
+
{errorsToRender.map((e) => (
{e}
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/progress-bar.tsx b/exercises/02.authentication/01.solution.basic/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/progress-bar.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/search-bar.tsx b/exercises/02.authentication/01.solution.basic/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/search-bar.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/spacer.tsx b/exercises/02.authentication/01.solution.basic/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/spacer.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/toaster.tsx b/exercises/02.authentication/01.solution.basic/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/toaster.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/README.md b/exercises/02.authentication/01.solution.basic/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/README.md
rename to exercises/02.authentication/01.solution.basic/app/components/ui/README.md
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/button.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/button.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/checkbox.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/checkbox.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/dropdown-menu.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/dropdown-menu.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/icon.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/icon.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/input-otp.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/input-otp.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/input.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/input.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/label.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/label.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/sonner.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/sonner.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/status-button.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/status-button.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/textarea.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/textarea.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/ui/tooltip.tsx b/exercises/02.authentication/01.solution.basic/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/ui/tooltip.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/user-dropdown.tsx b/exercises/02.authentication/01.solution.basic/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/user-dropdown.tsx
rename to exercises/02.authentication/01.solution.basic/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/entry.client.tsx b/exercises/02.authentication/01.solution.basic/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/entry.client.tsx
rename to exercises/02.authentication/01.solution.basic/app/entry.client.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/entry.server.tsx b/exercises/02.authentication/01.solution.basic/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/entry.server.tsx
rename to exercises/02.authentication/01.solution.basic/app/entry.server.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/root.tsx b/exercises/02.authentication/01.solution.basic/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/root.tsx
rename to exercises/02.authentication/01.solution.basic/app/root.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes.ts b/exercises/02.authentication/01.solution.basic/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes.ts
rename to exercises/02.authentication/01.solution.basic/app/routes.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/$.tsx b/exercises/02.authentication/01.solution.basic/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/$.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/$.tsx
diff --git a/exercises/04.debugging/03.problem.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 97%
rename from exercises/04.debugging/03.problem.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth.$provider.callback.test.ts
index 643e453..3765dd7 100644
--- a/exercises/04.debugging/03.problem.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts
+++ b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth.$provider.callback.test.ts
@@ -9,7 +9,7 @@ import { GITHUB_PROVIDER_NAME } from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { generateTOTP } from '#app/utils/totp.server.ts'
-import { createUser } from '#tests/db-utils.ts'
+import { generateUserInfo } from '#tests/db-utils.ts'
import { insertGitHubUser, deleteGitHubUsers } from '#tests/mocks/github.ts'
import { server } from '#tests/mocks/index.ts'
import { consoleError } from '#tests/setup/setup-test-env.ts'
@@ -109,7 +109,7 @@ test(`when a user is logged in and has already connected, it doesn't do anything
test('when a user exists with the same email, create connection and make session', async () => {
const githubUser = await insertGitHubUser()
const email = githubUser.primaryEmail.toLowerCase()
- const { userId } = await setupUser({ ...createUser(), email })
+ const { userId } = await setupUser({ ...generateUserInfo(), email })
const request = await setupRequest({ code: githubUser.code })
const response = await loader({ request, params: PARAMS, context: {} })
@@ -141,7 +141,7 @@ test('gives an error if the account is already connected to another user', async
const githubUser = await insertGitHubUser()
await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
connections: {
create: {
providerName: GITHUB_PROVIDER_NAME,
@@ -245,7 +245,7 @@ async function setupRequest({
return request
}
-async function setupUser(userData = createUser()) {
+async function setupUser(userData = generateUserInfo()) {
const session = await prisma.session.create({
data: {
expirationDate: getSessionExpirationDate(),
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth.$provider.callback.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth_.$provider.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth_.$provider.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/forgot-password.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/forgot-password.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/login.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/login.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/login.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/login.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/logout.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/logout.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/reset-password.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/reset-password.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/reset-password.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/reset-password.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/signup.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/signup.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/verify.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/verify.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/verify.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/verify.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/authentication.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/registration.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/about.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/about.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/index.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/index.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/docker.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/docker.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/eslint.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/eslint.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/faker.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/faker.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/fly.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/fly.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/github.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/github.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/logos.ts b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/logos.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/msw.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/msw.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/playwright.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/playwright.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/prettier.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/prettier.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/prisma.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/prisma.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/radix.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/radix.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/react-email.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/react-email.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/remix.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/remix.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/resend.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/resend.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/sentry.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/sentry.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/sqlite.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/stars.jpg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/stars.jpg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/tailwind.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/testing-library.png b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/testing-library.png
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/typescript.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/typescript.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/vitest.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/vitest.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/zod.svg b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/logos/zod.svg
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/privacy.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/privacy.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/support.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/support.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/tos.tsx b/exercises/02.authentication/01.solution.basic/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_marketing+/tos.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_seo+/robots[.]txt.ts b/exercises/02.authentication/01.solution.basic/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_seo+/robots[.]txt.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_seo+/sitemap[.]xml.ts b/exercises/02.authentication/01.solution.basic/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache.tsx b/exercises/02.authentication/01.solution.basic/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.server.ts b/exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.tsx b/exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/me.tsx b/exercises/02.authentication/01.solution.basic/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/me.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/me.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/resources+/download-user-data.tsx b/exercises/02.authentication/01.solution.basic/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/resources+/download-user-data.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/resources+/healthcheck.tsx b/exercises/02.authentication/01.solution.basic/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/resources+/healthcheck.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/resources+/images.tsx b/exercises/02.authentication/01.solution.basic/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/resources+/images.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/resources+/theme-switch.tsx b/exercises/02.authentication/01.solution.basic/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/resources+/theme-switch.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.change-email.server.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.change-email.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.change-email.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.connections.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.connections.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.index.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.index.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.passkeys.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.passkeys.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.password.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.password.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.password_.create.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.password_.create.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.photo.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.photo.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.index.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/04.debugging/02.problem.trace-viewer/app/routes/users+/$username.test.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username.test.tsx
similarity index 93%
rename from exercises/04.debugging/02.problem.trace-viewer/app/routes/users+/$username.test.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username.test.tsx
index b0784bd..0884a24 100644
--- a/exercises/04.debugging/02.problem.trace-viewer/app/routes/users+/$username.test.tsx
+++ b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username.test.tsx
@@ -10,7 +10,7 @@ import { loader as rootLoader } from '#app/root.tsx'
import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
-import { createUser, getUserImages } from '#tests/db-utils.ts'
+import { generateUserInfo, getUserImages } from '#tests/db-utils.ts'
import { default as UsernameRoute, loader } from './$username.tsx'
test('The user profile when not logged in as self', async () => {
@@ -19,7 +19,7 @@ test('The user profile when not logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const App = createRoutesStub([
{
@@ -44,7 +44,7 @@ test('The user profile when logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const session = await prisma.session.create({
select: { id: true },
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/__note-editor.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.index.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.new.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username_+/notes.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/index.tsx b/exercises/02.authentication/01.solution.basic/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/index.tsx
rename to exercises/02.authentication/01.solution.basic/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/styles/tailwind.css b/exercises/02.authentication/01.solution.basic/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/styles/tailwind.css
rename to exercises/02.authentication/01.solution.basic/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/auth.server.test.ts b/exercises/02.authentication/01.solution.basic/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/auth.server.test.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/auth.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/auth.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/cache.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/cache.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/client-hints.tsx b/exercises/02.authentication/01.solution.basic/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/client-hints.tsx
rename to exercises/02.authentication/01.solution.basic/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/connections.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/connections.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/connections.tsx b/exercises/02.authentication/01.solution.basic/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/connections.tsx
rename to exercises/02.authentication/01.solution.basic/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/db.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/db.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/email.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/email.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/env.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/env.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/headers.server.test.ts b/exercises/02.authentication/01.solution.basic/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/headers.server.test.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/headers.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/headers.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/honeypot.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/honeypot.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/litefs.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/litefs.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/misc.error-message.test.ts b/exercises/02.authentication/01.solution.basic/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/misc.error-message.test.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/misc.tsx b/exercises/02.authentication/01.solution.basic/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/misc.tsx
rename to exercises/02.authentication/01.solution.basic/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/misc.use-double-check.test.tsx b/exercises/02.authentication/01.solution.basic/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/misc.use-double-check.test.tsx
rename to exercises/02.authentication/01.solution.basic/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/monitoring.client.tsx b/exercises/02.authentication/01.solution.basic/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/monitoring.client.tsx
rename to exercises/02.authentication/01.solution.basic/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/nonce-provider.ts b/exercises/02.authentication/01.solution.basic/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/nonce-provider.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/permissions.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/permissions.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/providers/constants.ts b/exercises/02.authentication/01.solution.basic/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/providers/constants.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/providers/github.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/providers/github.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/providers/provider.ts b/exercises/02.authentication/01.solution.basic/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/providers/provider.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/redirect-cookie.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/redirect-cookie.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/request-info.ts b/exercises/02.authentication/01.solution.basic/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/request-info.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/session.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/session.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/storage.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/storage.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/theme.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/theme.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/timing.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/timing.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/toast.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/toast.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/totp.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/totp.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/user-validation.ts b/exercises/02.authentication/01.solution.basic/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/user-validation.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/user.ts b/exercises/02.authentication/01.solution.basic/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/user.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/user.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/app/utils/verification.server.ts b/exercises/02.authentication/01.solution.basic/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/utils/verification.server.ts
rename to exercises/02.authentication/01.solution.basic/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/components.json b/exercises/02.authentication/01.solution.basic/components.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/components.json
rename to exercises/02.authentication/01.solution.basic/components.json
diff --git a/exercises/02.test-setup/03.problem.authentication/eslint.config.js b/exercises/02.authentication/01.solution.basic/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/eslint.config.js
rename to exercises/02.authentication/01.solution.basic/eslint.config.js
diff --git a/exercises/02.test-setup/03.problem.authentication/fly.toml b/exercises/02.authentication/01.solution.basic/fly.toml
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/fly.toml
rename to exercises/02.authentication/01.solution.basic/fly.toml
diff --git a/exercises/02.test-setup/03.problem.authentication/index.js b/exercises/02.authentication/01.solution.basic/index.js
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/index.js
rename to exercises/02.authentication/01.solution.basic/index.js
diff --git a/exercises/02.test-setup/03.problem.authentication/other/Dockerfile b/exercises/02.authentication/01.solution.basic/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/Dockerfile
rename to exercises/02.authentication/01.solution.basic/other/Dockerfile
diff --git a/exercises/02.test-setup/03.problem.authentication/other/Dockerfile.dockerignore b/exercises/02.authentication/01.solution.basic/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/Dockerfile.dockerignore
rename to exercises/02.authentication/01.solution.basic/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/03.problem.authentication/other/README.md b/exercises/02.authentication/01.solution.basic/other/README.md
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/README.md
rename to exercises/02.authentication/01.solution.basic/other/README.md
diff --git a/exercises/02.test-setup/03.problem.authentication/other/build-server.ts b/exercises/02.authentication/01.solution.basic/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/build-server.ts
rename to exercises/02.authentication/01.solution.basic/other/build-server.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/other/litefs.yml b/exercises/02.authentication/01.solution.basic/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/litefs.yml
rename to exercises/02.authentication/01.solution.basic/other/litefs.yml
diff --git a/exercises/02.test-setup/03.problem.authentication/other/sly/sly.json b/exercises/02.authentication/01.solution.basic/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/sly/sly.json
rename to exercises/02.authentication/01.solution.basic/other/sly/sly.json
diff --git a/exercises/02.test-setup/03.problem.authentication/other/sly/transform-icon.ts b/exercises/02.authentication/01.solution.basic/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/sly/transform-icon.ts
rename to exercises/02.authentication/01.solution.basic/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/README.md b/exercises/02.authentication/01.solution.basic/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/README.md
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/arrow-left.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/arrow-left.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/arrow-right.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/arrow-right.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/avatar.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/avatar.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/camera.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/camera.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/check.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/check.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/clock.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/clock.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/cross-1.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/cross-1.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/dots-horizontal.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/dots-horizontal.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/download.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/download.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/envelope-closed.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/envelope-closed.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/exit.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/exit.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/file-text.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/file-text.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/github-logo.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/github-logo.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/laptop.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/laptop.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/link-2.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/link-2.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/lock-closed.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/lock-closed.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/lock-open-1.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/lock-open-1.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/magnifying-glass.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/magnifying-glass.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/moon.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/moon.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/passkey.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/passkey.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/pencil-1.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/pencil-1.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/pencil-2.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/pencil-2.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/plus.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/plus.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/question-mark-circled.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/question-mark-circled.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/reset.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/reset.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/sun.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/sun.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/trash.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/trash.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/other/svg-icons/update.svg b/exercises/02.authentication/01.solution.basic/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/other/svg-icons/update.svg
rename to exercises/02.authentication/01.solution.basic/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/03.problem.authentication/package-lock.json b/exercises/02.authentication/01.solution.basic/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/package-lock.json
rename to exercises/02.authentication/01.solution.basic/package-lock.json
diff --git a/exercises/02.test-setup/05.solution.test-data/package.json b/exercises/02.authentication/01.solution.basic/package.json
similarity index 98%
rename from exercises/02.test-setup/05.solution.test-data/package.json
rename to exercises/02.authentication/01.solution.basic/package.json
index e5f4b2a..6297875 100644
--- a/exercises/02.test-setup/05.solution.test-data/package.json
+++ b/exercises/02.authentication/01.solution.basic/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_05.solution.test-data",
+ "name": "exercises_02.authentication_01.solution.basic",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/02.test-setup/03.problem.authentication/playwright.config.ts b/exercises/02.authentication/01.solution.basic/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/playwright.config.ts
rename to exercises/02.authentication/01.solution.basic/playwright.config.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/prisma/migrations/20250221233640_init/migration.sql b/exercises/02.authentication/01.solution.basic/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/02.authentication/01.solution.basic/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/03.problem.authentication/prisma/migrations/migration_lock.toml b/exercises/02.authentication/01.solution.basic/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/prisma/migrations/migration_lock.toml
rename to exercises/02.authentication/01.solution.basic/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/03.problem.authentication/prisma/schema.prisma b/exercises/02.authentication/01.solution.basic/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/prisma/schema.prisma
rename to exercises/02.authentication/01.solution.basic/prisma/schema.prisma
diff --git a/exercises/04.debugging/02.problem.trace-viewer/prisma/seed.ts b/exercises/02.authentication/01.solution.basic/prisma/seed.ts
similarity index 99%
rename from exercises/04.debugging/02.problem.trace-viewer/prisma/seed.ts
rename to exercises/02.authentication/01.solution.basic/prisma/seed.ts
index 8454353..521e1d5 100644
--- a/exercises/04.debugging/02.problem.trace-viewer/prisma/seed.ts
+++ b/exercises/02.authentication/01.solution.basic/prisma/seed.ts
@@ -3,7 +3,7 @@ import { prisma } from '#app/utils/db.server.ts'
import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants'
import {
createPassword,
- createUser,
+ generateUserInfo,
getNoteImages,
getUserImages,
} from '#tests/db-utils.ts'
@@ -19,7 +19,7 @@ async function seed() {
const userImages = await getUserImages()
for (let index = 0; index < totalUsers; index++) {
- const userData = createUser()
+ const userData = generateUserInfo()
const user = await prisma.user.create({
select: { id: true },
data: {
diff --git a/exercises/02.test-setup/03.problem.authentication/prisma/sql/searchUsers.sql b/exercises/02.authentication/01.solution.basic/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/prisma/sql/searchUsers.sql
rename to exercises/02.authentication/01.solution.basic/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/03.problem.authentication/public/favicon.ico b/exercises/02.authentication/01.solution.basic/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/favicon.ico
rename to exercises/02.authentication/01.solution.basic/public/favicon.ico
diff --git a/exercises/02.test-setup/03.problem.authentication/public/favicons/README.md b/exercises/02.authentication/01.solution.basic/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/favicons/README.md
rename to exercises/02.authentication/01.solution.basic/public/favicons/README.md
diff --git a/exercises/02.test-setup/03.problem.authentication/public/favicons/android-chrome-192x192.png b/exercises/02.authentication/01.solution.basic/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/favicons/android-chrome-192x192.png
rename to exercises/02.authentication/01.solution.basic/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/03.problem.authentication/public/favicons/android-chrome-512x512.png b/exercises/02.authentication/01.solution.basic/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/favicons/android-chrome-512x512.png
rename to exercises/02.authentication/01.solution.basic/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/03.problem.authentication/public/img/user.png b/exercises/02.authentication/01.solution.basic/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/img/user.png
rename to exercises/02.authentication/01.solution.basic/public/img/user.png
diff --git a/exercises/02.test-setup/03.problem.authentication/public/site.webmanifest b/exercises/02.authentication/01.solution.basic/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/public/site.webmanifest
rename to exercises/02.authentication/01.solution.basic/public/site.webmanifest
diff --git a/exercises/02.test-setup/03.problem.authentication/react-router.config.ts b/exercises/02.authentication/01.solution.basic/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/react-router.config.ts
rename to exercises/02.authentication/01.solution.basic/react-router.config.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/server/dev-server.js b/exercises/02.authentication/01.solution.basic/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/server/dev-server.js
rename to exercises/02.authentication/01.solution.basic/server/dev-server.js
diff --git a/exercises/02.test-setup/03.problem.authentication/server/index.ts b/exercises/02.authentication/01.solution.basic/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/server/index.ts
rename to exercises/02.authentication/01.solution.basic/server/index.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/server/utils/monitoring.ts b/exercises/02.authentication/01.solution.basic/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/server/utils/monitoring.ts
rename to exercises/02.authentication/01.solution.basic/server/utils/monitoring.ts
diff --git a/exercises/04.debugging/03.solution.live-debugging/tests/db-utils.ts b/exercises/02.authentication/01.solution.basic/tests/db-utils.ts
similarity index 66%
rename from exercises/04.debugging/03.solution.live-debugging/tests/db-utils.ts
rename to exercises/02.authentication/01.solution.basic/tests/db-utils.ts
index f701a8a..62543fe 100644
--- a/exercises/04.debugging/03.solution.live-debugging/tests/db-utils.ts
+++ b/exercises/02.authentication/01.solution.basic/tests/db-utils.ts
@@ -1,10 +1,12 @@
import { faker } from '@faker-js/faker'
import bcrypt from 'bcryptjs'
import { UniqueEnforcer } from 'enforce-unique'
+import { getPasswordHash } from '#app/utils/auth.server.ts'
+import { prisma } from '#app/utils/db.server.ts'
const uniqueUsernameEnforcer = new UniqueEnforcer()
-export function createUser() {
+export function generateUserInfo() {
const firstName = faker.person.firstName()
const lastName = faker.person.lastName()
@@ -22,6 +24,7 @@ export function createUser() {
.slice(0, 20)
.toLowerCase()
.replace(/[^a-z0-9_]/g, '_')
+
return {
username,
name: `${firstName} ${lastName}`,
@@ -29,6 +32,59 @@ export function createUser() {
}
}
+export async function createUser() {
+ const userInfo = generateUserInfo()
+ const password = 'supersecret'
+ const user = await prisma.user.create({
+ data: {
+ ...userInfo,
+ password: { create: { hash: await getPasswordHash(password) } },
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.user.deleteMany({
+ where: { id: user.id },
+ })
+ },
+ ...user,
+ password,
+ }
+}
+
+export async function createPasskey(input: {
+ id: string
+ userId: string
+ aaguid: string
+ publicKey: Uint8Array
+ counter?: number
+}) {
+ const passkey = await prisma.passkey.create({
+ data: {
+ id: input.id,
+ aaguid: input.aaguid,
+ userId: input.userId,
+ publicKey: input.publicKey,
+ backedUp: false,
+ webauthnUserId: input.userId,
+ deviceType: 'singleDevice',
+ counter: input.counter || 0,
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.passkey.deleteMany({
+ where: {
+ id: passkey.id,
+ },
+ })
+ },
+ ...passkey,
+ }
+}
+
export function createPassword(password: string = faker.internet.password()) {
return {
hash: bcrypt.hashSync(password, 10),
diff --git a/exercises/02.authentication/01.solution.basic/tests/e2e/authentication-basic.test.ts b/exercises/02.authentication/01.solution.basic/tests/e2e/authentication-basic.test.ts
new file mode 100644
index 0000000..be7bb76
--- /dev/null
+++ b/exercises/02.authentication/01.solution.basic/tests/e2e/authentication-basic.test.ts
@@ -0,0 +1,29 @@
+import { createUser } from '#tests/db-utils.ts'
+import { test, expect } from '#tests/test-extend.ts'
+
+test('authenticates using a email and password', async ({ navigate, page }) => {
+ await using user = await createUser()
+
+ await navigate('/login')
+
+ await page.getByLabel('Username').fill(user.username)
+ await page.getByLabel('Password').fill(user.password)
+ await page.getByRole('button', { name: 'Log in' }).click()
+
+ await expect(page.getByText(user.name!)).toBeVisible()
+})
+
+test('displays an error message when authenticating with invalid credentials', async ({
+ navigate,
+ page,
+}) => {
+ await navigate('/login')
+
+ await page.getByLabel('Username').fill('non_existing_user')
+ await page.getByLabel('Password').fill('non_existing_password')
+ await page.getByRole('button', { name: 'Log in' }).click()
+
+ await expect(
+ page.getByRole('alert').getByText('Invalid username or password'),
+ ).toBeVisible()
+})
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/setup/custom-matchers.ts b/exercises/02.authentication/01.solution.basic/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/setup/custom-matchers.ts
rename to exercises/02.authentication/01.solution.basic/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/setup/db-setup.ts b/exercises/02.authentication/01.solution.basic/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/setup/db-setup.ts
rename to exercises/02.authentication/01.solution.basic/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/setup/global-setup.ts b/exercises/02.authentication/01.solution.basic/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/setup/global-setup.ts
rename to exercises/02.authentication/01.solution.basic/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/setup/setup-test-env.ts b/exercises/02.authentication/01.solution.basic/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/setup/setup-test-env.ts
rename to exercises/02.authentication/01.solution.basic/tests/setup/setup-test-env.ts
diff --git a/exercises/03.guides/02.problem.test-annotations/tests/test-extend.ts b/exercises/02.authentication/01.solution.basic/tests/test-extend.ts
similarity index 95%
rename from exercises/03.guides/02.problem.test-annotations/tests/test-extend.ts
rename to exercises/02.authentication/01.solution.basic/tests/test-extend.ts
index 8b8eed1..a51b50d 100644
--- a/exercises/03.guides/02.problem.test-annotations/tests/test-extend.ts
+++ b/exercises/02.authentication/01.solution.basic/tests/test-extend.ts
@@ -7,7 +7,7 @@ import {
import { href, type Register } from 'react-router'
import { getPasswordHash } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
-import { createUser } from '#tests/db-utils'
+import { generateUserInfo } from '#tests/db-utils'
interface Fixtures {
navigate: (
@@ -20,7 +20,7 @@ const user = definePersona('user', {
async createSession({ page }) {
const user = await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
roles: { connect: { name: 'user' } },
password: { create: { hash: await getPasswordHash('supersecret') } },
},
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/utils.ts b/exercises/02.authentication/01.solution.basic/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/utils.ts
rename to exercises/02.authentication/01.solution.basic/tests/utils.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tsconfig.json b/exercises/02.authentication/01.solution.basic/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tsconfig.json
rename to exercises/02.authentication/01.solution.basic/tsconfig.json
diff --git a/exercises/02.test-setup/03.problem.authentication/types/deps.d.ts b/exercises/02.authentication/01.solution.basic/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/types/deps.d.ts
rename to exercises/02.authentication/01.solution.basic/types/deps.d.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/types/env.env.d.ts b/exercises/02.authentication/01.solution.basic/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/types/env.env.d.ts
rename to exercises/02.authentication/01.solution.basic/types/env.env.d.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/types/icon-name.d.ts b/exercises/02.authentication/01.solution.basic/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/types/icon-name.d.ts
rename to exercises/02.authentication/01.solution.basic/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/types/reset.d.ts b/exercises/02.authentication/01.solution.basic/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/types/reset.d.ts
rename to exercises/02.authentication/01.solution.basic/types/reset.d.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/vite.config.ts b/exercises/02.authentication/01.solution.basic/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/vite.config.ts
rename to exercises/02.authentication/01.solution.basic/vite.config.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/.env b/exercises/02.authentication/02.solution.2fa/.env
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.env
rename to exercises/02.authentication/02.solution.2fa/.env
diff --git a/exercises/02.test-setup/03.solution.authentication/.env.example b/exercises/02.authentication/02.solution.2fa/.env.example
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.env.example
rename to exercises/02.authentication/02.solution.2fa/.env.example
diff --git a/exercises/02.test-setup/03.solution.authentication/.gitignore b/exercises/02.authentication/02.solution.2fa/.gitignore
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.gitignore
rename to exercises/02.authentication/02.solution.2fa/.gitignore
diff --git a/exercises/02.test-setup/03.solution.authentication/.npmrc b/exercises/02.authentication/02.solution.2fa/.npmrc
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.npmrc
rename to exercises/02.authentication/02.solution.2fa/.npmrc
diff --git a/exercises/02.test-setup/03.solution.authentication/.prettierignore b/exercises/02.authentication/02.solution.2fa/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.prettierignore
rename to exercises/02.authentication/02.solution.2fa/.prettierignore
diff --git a/exercises/02.test-setup/03.solution.authentication/.vscode/extensions.json b/exercises/02.authentication/02.solution.2fa/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.vscode/extensions.json
rename to exercises/02.authentication/02.solution.2fa/.vscode/extensions.json
diff --git a/exercises/02.test-setup/03.solution.authentication/.vscode/remix.code-snippets b/exercises/02.authentication/02.solution.2fa/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.vscode/remix.code-snippets
rename to exercises/02.authentication/02.solution.2fa/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/03.solution.authentication/.vscode/settings.json b/exercises/02.authentication/02.solution.2fa/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.vscode/settings.json
rename to exercises/02.authentication/02.solution.2fa/.vscode/settings.json
diff --git a/exercises/02.authentication/02.solution.2fa/README.mdx b/exercises/02.authentication/02.solution.2fa/README.mdx
new file mode 100644
index 0000000..a13a75f
--- /dev/null
+++ b/exercises/02.authentication/02.solution.2fa/README.mdx
@@ -0,0 +1 @@
+# Passkeys
\ No newline at end of file
diff --git a/exercises/02.test-setup/03.solution.authentication/app/assets/favicons/apple-touch-icon.png b/exercises/02.authentication/02.solution.2fa/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/assets/favicons/apple-touch-icon.png
rename to exercises/02.authentication/02.solution.2fa/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/03.solution.authentication/app/assets/favicons/favicon.svg b/exercises/02.authentication/02.solution.2fa/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/assets/favicons/favicon.svg
rename to exercises/02.authentication/02.solution.2fa/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/error-boundary.tsx b/exercises/02.authentication/02.solution.2fa/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/error-boundary.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/floating-toolbar.tsx b/exercises/02.authentication/02.solution.2fa/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/floating-toolbar.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/components/forms.tsx b/exercises/02.authentication/02.solution.2fa/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/components/forms.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/forms.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/progress-bar.tsx b/exercises/02.authentication/02.solution.2fa/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/progress-bar.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/search-bar.tsx b/exercises/02.authentication/02.solution.2fa/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/search-bar.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/spacer.tsx b/exercises/02.authentication/02.solution.2fa/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/spacer.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/toaster.tsx b/exercises/02.authentication/02.solution.2fa/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/toaster.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/README.md b/exercises/02.authentication/02.solution.2fa/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/README.md
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/README.md
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/button.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/button.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/checkbox.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/checkbox.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/dropdown-menu.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/dropdown-menu.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/icon.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/icon.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/input-otp.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/input-otp.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/input.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/input.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/label.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/label.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/sonner.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/sonner.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/status-button.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/status-button.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/textarea.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/textarea.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/ui/tooltip.tsx b/exercises/02.authentication/02.solution.2fa/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/ui/tooltip.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/user-dropdown.tsx b/exercises/02.authentication/02.solution.2fa/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/user-dropdown.tsx
rename to exercises/02.authentication/02.solution.2fa/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/entry.client.tsx b/exercises/02.authentication/02.solution.2fa/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/entry.client.tsx
rename to exercises/02.authentication/02.solution.2fa/app/entry.client.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/entry.server.tsx b/exercises/02.authentication/02.solution.2fa/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/entry.server.tsx
rename to exercises/02.authentication/02.solution.2fa/app/entry.server.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/root.tsx b/exercises/02.authentication/02.solution.2fa/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/root.tsx
rename to exercises/02.authentication/02.solution.2fa/app/root.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes.ts b/exercises/02.authentication/02.solution.2fa/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/$.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/$.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/$.tsx
diff --git a/exercises/04.debugging/02.problem.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 97%
rename from exercises/04.debugging/02.problem.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth.$provider.callback.test.ts
index 643e453..3765dd7 100644
--- a/exercises/04.debugging/02.problem.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts
+++ b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth.$provider.callback.test.ts
@@ -9,7 +9,7 @@ import { GITHUB_PROVIDER_NAME } from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { generateTOTP } from '#app/utils/totp.server.ts'
-import { createUser } from '#tests/db-utils.ts'
+import { generateUserInfo } from '#tests/db-utils.ts'
import { insertGitHubUser, deleteGitHubUsers } from '#tests/mocks/github.ts'
import { server } from '#tests/mocks/index.ts'
import { consoleError } from '#tests/setup/setup-test-env.ts'
@@ -109,7 +109,7 @@ test(`when a user is logged in and has already connected, it doesn't do anything
test('when a user exists with the same email, create connection and make session', async () => {
const githubUser = await insertGitHubUser()
const email = githubUser.primaryEmail.toLowerCase()
- const { userId } = await setupUser({ ...createUser(), email })
+ const { userId } = await setupUser({ ...generateUserInfo(), email })
const request = await setupRequest({ code: githubUser.code })
const response = await loader({ request, params: PARAMS, context: {} })
@@ -141,7 +141,7 @@ test('gives an error if the account is already connected to another user', async
const githubUser = await insertGitHubUser()
await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
connections: {
create: {
providerName: GITHUB_PROVIDER_NAME,
@@ -245,7 +245,7 @@ async function setupRequest({
return request
}
-async function setupUser(userData = createUser()) {
+async function setupUser(userData = generateUserInfo()) {
const session = await prisma.session.create({
data: {
expirationDate: getSessionExpirationDate(),
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth.$provider.callback.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth_.$provider.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth_.$provider.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/forgot-password.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/forgot-password.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/login.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/login.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/login.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/login.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/logout.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/logout.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/reset-password.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/reset-password.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/reset-password.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/reset-password.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/signup.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/signup.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/verify.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/verify.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/verify.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/verify.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/authentication.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/registration.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/about.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/about.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/index.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/index.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/docker.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/docker.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/eslint.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/eslint.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/faker.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/faker.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/fly.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/fly.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/github.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/github.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/logos.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/logos.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/msw.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/msw.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/playwright.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/playwright.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/prettier.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/prettier.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/prisma.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/prisma.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/radix.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/radix.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/react-email.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/react-email.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/remix.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/remix.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/resend.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/resend.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/sentry.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/sentry.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/sqlite.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/stars.jpg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/stars.jpg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/tailwind.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/testing-library.png b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/testing-library.png
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/typescript.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/typescript.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/vitest.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/vitest.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/zod.svg b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/logos/zod.svg
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/privacy.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/privacy.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/support.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/support.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/tos.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_marketing+/tos.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_seo+/robots[.]txt.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_seo+/robots[.]txt.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_seo+/sitemap[.]xml.ts b/exercises/02.authentication/02.solution.2fa/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.server.ts b/exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/me.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/me.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/me.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/resources+/download-user-data.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/resources+/download-user-data.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/resources+/healthcheck.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/resources+/healthcheck.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/resources+/images.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/resources+/images.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/resources+/theme-switch.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/resources+/theme-switch.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.change-email.server.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.change-email.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.change-email.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.connections.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.connections.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.index.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.index.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.passkeys.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.passkeys.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.password.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.password.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.password_.create.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.password_.create.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.photo.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.photo.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.index.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/04.debugging/03.problem.live-debugging/app/routes/users+/$username.test.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username.test.tsx
similarity index 93%
rename from exercises/04.debugging/03.problem.live-debugging/app/routes/users+/$username.test.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username.test.tsx
index b0784bd..0884a24 100644
--- a/exercises/04.debugging/03.problem.live-debugging/app/routes/users+/$username.test.tsx
+++ b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username.test.tsx
@@ -10,7 +10,7 @@ import { loader as rootLoader } from '#app/root.tsx'
import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
-import { createUser, getUserImages } from '#tests/db-utils.ts'
+import { generateUserInfo, getUserImages } from '#tests/db-utils.ts'
import { default as UsernameRoute, loader } from './$username.tsx'
test('The user profile when not logged in as self', async () => {
@@ -19,7 +19,7 @@ test('The user profile when not logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const App = createRoutesStub([
{
@@ -44,7 +44,7 @@ test('The user profile when logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const session = await prisma.session.create({
select: { id: true },
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/__note-editor.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.index.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.new.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username_+/notes.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/index.tsx b/exercises/02.authentication/02.solution.2fa/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/index.tsx
rename to exercises/02.authentication/02.solution.2fa/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/styles/tailwind.css b/exercises/02.authentication/02.solution.2fa/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/styles/tailwind.css
rename to exercises/02.authentication/02.solution.2fa/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/auth.server.test.ts b/exercises/02.authentication/02.solution.2fa/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/auth.server.test.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/auth.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/auth.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/cache.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/cache.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/client-hints.tsx b/exercises/02.authentication/02.solution.2fa/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/client-hints.tsx
rename to exercises/02.authentication/02.solution.2fa/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/connections.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/connections.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/connections.tsx b/exercises/02.authentication/02.solution.2fa/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/connections.tsx
rename to exercises/02.authentication/02.solution.2fa/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/db.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/db.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/email.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/email.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/env.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/env.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/headers.server.test.ts b/exercises/02.authentication/02.solution.2fa/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/headers.server.test.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/headers.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/headers.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/honeypot.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/honeypot.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/litefs.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/litefs.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/misc.error-message.test.ts b/exercises/02.authentication/02.solution.2fa/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/misc.error-message.test.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/misc.tsx b/exercises/02.authentication/02.solution.2fa/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/misc.tsx
rename to exercises/02.authentication/02.solution.2fa/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/misc.use-double-check.test.tsx b/exercises/02.authentication/02.solution.2fa/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/misc.use-double-check.test.tsx
rename to exercises/02.authentication/02.solution.2fa/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/monitoring.client.tsx b/exercises/02.authentication/02.solution.2fa/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/monitoring.client.tsx
rename to exercises/02.authentication/02.solution.2fa/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/nonce-provider.ts b/exercises/02.authentication/02.solution.2fa/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/nonce-provider.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/permissions.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/permissions.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/providers/constants.ts b/exercises/02.authentication/02.solution.2fa/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/providers/constants.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/providers/github.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/providers/github.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/providers/provider.ts b/exercises/02.authentication/02.solution.2fa/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/providers/provider.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/redirect-cookie.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/redirect-cookie.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/request-info.ts b/exercises/02.authentication/02.solution.2fa/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/request-info.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/session.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/session.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/storage.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/storage.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/theme.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/theme.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/timing.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/timing.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/toast.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/toast.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/totp.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/totp.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/user-validation.ts b/exercises/02.authentication/02.solution.2fa/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/user-validation.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/user.ts b/exercises/02.authentication/02.solution.2fa/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/user.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/user.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/app/utils/verification.server.ts b/exercises/02.authentication/02.solution.2fa/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/utils/verification.server.ts
rename to exercises/02.authentication/02.solution.2fa/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/components.json b/exercises/02.authentication/02.solution.2fa/components.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/components.json
rename to exercises/02.authentication/02.solution.2fa/components.json
diff --git a/exercises/02.test-setup/03.solution.authentication/eslint.config.js b/exercises/02.authentication/02.solution.2fa/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/eslint.config.js
rename to exercises/02.authentication/02.solution.2fa/eslint.config.js
diff --git a/exercises/02.test-setup/03.solution.authentication/fly.toml b/exercises/02.authentication/02.solution.2fa/fly.toml
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/fly.toml
rename to exercises/02.authentication/02.solution.2fa/fly.toml
diff --git a/exercises/02.test-setup/03.solution.authentication/index.js b/exercises/02.authentication/02.solution.2fa/index.js
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/index.js
rename to exercises/02.authentication/02.solution.2fa/index.js
diff --git a/exercises/02.test-setup/03.solution.authentication/other/Dockerfile b/exercises/02.authentication/02.solution.2fa/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/Dockerfile
rename to exercises/02.authentication/02.solution.2fa/other/Dockerfile
diff --git a/exercises/02.test-setup/03.solution.authentication/other/Dockerfile.dockerignore b/exercises/02.authentication/02.solution.2fa/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/Dockerfile.dockerignore
rename to exercises/02.authentication/02.solution.2fa/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/03.solution.authentication/other/README.md b/exercises/02.authentication/02.solution.2fa/other/README.md
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/README.md
rename to exercises/02.authentication/02.solution.2fa/other/README.md
diff --git a/exercises/02.test-setup/03.solution.authentication/other/build-server.ts b/exercises/02.authentication/02.solution.2fa/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/build-server.ts
rename to exercises/02.authentication/02.solution.2fa/other/build-server.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/other/litefs.yml b/exercises/02.authentication/02.solution.2fa/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/litefs.yml
rename to exercises/02.authentication/02.solution.2fa/other/litefs.yml
diff --git a/exercises/02.test-setup/03.solution.authentication/other/sly/sly.json b/exercises/02.authentication/02.solution.2fa/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/sly/sly.json
rename to exercises/02.authentication/02.solution.2fa/other/sly/sly.json
diff --git a/exercises/02.test-setup/03.solution.authentication/other/sly/transform-icon.ts b/exercises/02.authentication/02.solution.2fa/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/sly/transform-icon.ts
rename to exercises/02.authentication/02.solution.2fa/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/README.md b/exercises/02.authentication/02.solution.2fa/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/README.md
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/arrow-left.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/arrow-left.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/arrow-right.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/arrow-right.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/avatar.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/avatar.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/camera.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/camera.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/check.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/check.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/clock.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/clock.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/cross-1.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/cross-1.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/dots-horizontal.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/dots-horizontal.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/download.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/download.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/envelope-closed.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/envelope-closed.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/exit.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/exit.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/file-text.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/file-text.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/github-logo.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/github-logo.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/laptop.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/laptop.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/link-2.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/link-2.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/lock-closed.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/lock-closed.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/lock-open-1.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/lock-open-1.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/magnifying-glass.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/magnifying-glass.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/moon.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/moon.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/passkey.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/passkey.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/pencil-1.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/pencil-1.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/pencil-2.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/pencil-2.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/plus.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/plus.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/question-mark-circled.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/question-mark-circled.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/reset.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/reset.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/sun.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/sun.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/trash.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/trash.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/other/svg-icons/update.svg b/exercises/02.authentication/02.solution.2fa/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/other/svg-icons/update.svg
rename to exercises/02.authentication/02.solution.2fa/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/03.solution.authentication/package-lock.json b/exercises/02.authentication/02.solution.2fa/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/package-lock.json
rename to exercises/02.authentication/02.solution.2fa/package-lock.json
diff --git a/exercises/02.test-setup/03.problem.authentication/package.json b/exercises/02.authentication/02.solution.2fa/package.json
similarity index 98%
rename from exercises/02.test-setup/03.problem.authentication/package.json
rename to exercises/02.authentication/02.solution.2fa/package.json
index fdab506..f3f70d4 100644
--- a/exercises/02.test-setup/03.problem.authentication/package.json
+++ b/exercises/02.authentication/02.solution.2fa/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_03.problem.authentication",
+ "name": "exercises_02.authentication_02.solution.2fa",
"private": true,
"sideEffects": false,
"type": "module",
@@ -151,6 +151,7 @@
"prettier-plugin-tailwindcss": "^0.6.11",
"react-router-devtools": "^5.0.5",
"remix-flat-routes": "^0.8.5",
+ "test-passkey": "^1.0.1",
"tsx": "^4.19.4",
"tw-animate-css": "^1.2.9",
"typescript": "^5.8.3",
diff --git a/exercises/02.test-setup/03.solution.authentication/playwright.config.ts b/exercises/02.authentication/02.solution.2fa/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/playwright.config.ts
rename to exercises/02.authentication/02.solution.2fa/playwright.config.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/prisma/migrations/20250221233640_init/migration.sql b/exercises/02.authentication/02.solution.2fa/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/02.authentication/02.solution.2fa/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/03.solution.authentication/prisma/migrations/migration_lock.toml b/exercises/02.authentication/02.solution.2fa/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/prisma/migrations/migration_lock.toml
rename to exercises/02.authentication/02.solution.2fa/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/03.solution.authentication/prisma/schema.prisma b/exercises/02.authentication/02.solution.2fa/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/prisma/schema.prisma
rename to exercises/02.authentication/02.solution.2fa/prisma/schema.prisma
diff --git a/exercises/04.debugging/03.problem.live-debugging/prisma/seed.ts b/exercises/02.authentication/02.solution.2fa/prisma/seed.ts
similarity index 99%
rename from exercises/04.debugging/03.problem.live-debugging/prisma/seed.ts
rename to exercises/02.authentication/02.solution.2fa/prisma/seed.ts
index 8454353..521e1d5 100644
--- a/exercises/04.debugging/03.problem.live-debugging/prisma/seed.ts
+++ b/exercises/02.authentication/02.solution.2fa/prisma/seed.ts
@@ -3,7 +3,7 @@ import { prisma } from '#app/utils/db.server.ts'
import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants'
import {
createPassword,
- createUser,
+ generateUserInfo,
getNoteImages,
getUserImages,
} from '#tests/db-utils.ts'
@@ -19,7 +19,7 @@ async function seed() {
const userImages = await getUserImages()
for (let index = 0; index < totalUsers; index++) {
- const userData = createUser()
+ const userData = generateUserInfo()
const user = await prisma.user.create({
select: { id: true },
data: {
diff --git a/exercises/02.test-setup/03.solution.authentication/prisma/sql/searchUsers.sql b/exercises/02.authentication/02.solution.2fa/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/prisma/sql/searchUsers.sql
rename to exercises/02.authentication/02.solution.2fa/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/03.solution.authentication/public/favicon.ico b/exercises/02.authentication/02.solution.2fa/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/favicon.ico
rename to exercises/02.authentication/02.solution.2fa/public/favicon.ico
diff --git a/exercises/02.test-setup/03.solution.authentication/public/favicons/README.md b/exercises/02.authentication/02.solution.2fa/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/favicons/README.md
rename to exercises/02.authentication/02.solution.2fa/public/favicons/README.md
diff --git a/exercises/02.test-setup/03.solution.authentication/public/favicons/android-chrome-192x192.png b/exercises/02.authentication/02.solution.2fa/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/favicons/android-chrome-192x192.png
rename to exercises/02.authentication/02.solution.2fa/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/03.solution.authentication/public/favicons/android-chrome-512x512.png b/exercises/02.authentication/02.solution.2fa/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/favicons/android-chrome-512x512.png
rename to exercises/02.authentication/02.solution.2fa/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/03.solution.authentication/public/img/user.png b/exercises/02.authentication/02.solution.2fa/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/img/user.png
rename to exercises/02.authentication/02.solution.2fa/public/img/user.png
diff --git a/exercises/02.test-setup/03.solution.authentication/public/site.webmanifest b/exercises/02.authentication/02.solution.2fa/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/public/site.webmanifest
rename to exercises/02.authentication/02.solution.2fa/public/site.webmanifest
diff --git a/exercises/02.test-setup/03.solution.authentication/react-router.config.ts b/exercises/02.authentication/02.solution.2fa/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/react-router.config.ts
rename to exercises/02.authentication/02.solution.2fa/react-router.config.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/server/dev-server.js b/exercises/02.authentication/02.solution.2fa/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/server/dev-server.js
rename to exercises/02.authentication/02.solution.2fa/server/dev-server.js
diff --git a/exercises/02.test-setup/03.solution.authentication/server/index.ts b/exercises/02.authentication/02.solution.2fa/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/server/index.ts
rename to exercises/02.authentication/02.solution.2fa/server/index.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/server/utils/monitoring.ts b/exercises/02.authentication/02.solution.2fa/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/server/utils/monitoring.ts
rename to exercises/02.authentication/02.solution.2fa/server/utils/monitoring.ts
diff --git a/exercises/04.debugging/03.problem.live-debugging/tests/db-utils.ts b/exercises/02.authentication/02.solution.2fa/tests/db-utils.ts
similarity index 68%
rename from exercises/04.debugging/03.problem.live-debugging/tests/db-utils.ts
rename to exercises/02.authentication/02.solution.2fa/tests/db-utils.ts
index f701a8a..3b58c39 100644
--- a/exercises/04.debugging/03.problem.live-debugging/tests/db-utils.ts
+++ b/exercises/02.authentication/02.solution.2fa/tests/db-utils.ts
@@ -1,10 +1,13 @@
+import { type generateTOTP } from '@epic-web/totp'
import { faker } from '@faker-js/faker'
import bcrypt from 'bcryptjs'
import { UniqueEnforcer } from 'enforce-unique'
+import { getPasswordHash } from '#app/utils/auth.server.ts'
+import { prisma } from '#app/utils/db.server.ts'
const uniqueUsernameEnforcer = new UniqueEnforcer()
-export function createUser() {
+export function generateUserInfo() {
const firstName = faker.person.firstName()
const lastName = faker.person.lastName()
@@ -22,6 +25,7 @@ export function createUser() {
.slice(0, 20)
.toLowerCase()
.replace(/[^a-z0-9_]/g, '_')
+
return {
username,
name: `${firstName} ${lastName}`,
@@ -29,6 +33,50 @@ export function createUser() {
}
}
+export async function createUser() {
+ const userInfo = generateUserInfo()
+ const password = 'supersecret'
+ const user = await prisma.user.create({
+ data: {
+ ...userInfo,
+ password: { create: { hash: await getPasswordHash(password) } },
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.user.deleteMany({
+ where: { id: user.id },
+ })
+ },
+ ...user,
+ password,
+ }
+}
+
+export async function createVerification(input: {
+ totp: Awaited>
+ userId: string
+}) {
+ const { otp, ...totpConfig } = input.totp
+ const verification = await prisma.verification.create({
+ data: {
+ ...totpConfig,
+ type: '2fa',
+ target: input.userId,
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.verification.deleteMany({
+ where: { id: verification.id },
+ })
+ },
+ ...verification,
+ }
+}
+
export function createPassword(password: string = faker.internet.password()) {
return {
hash: bcrypt.hashSync(password, 10),
diff --git a/exercises/02.authentication/02.solution.2fa/tests/e2e/authentication-2fa.test.ts b/exercises/02.authentication/02.solution.2fa/tests/e2e/authentication-2fa.test.ts
new file mode 100644
index 0000000..3ea630a
--- /dev/null
+++ b/exercises/02.authentication/02.solution.2fa/tests/e2e/authentication-2fa.test.ts
@@ -0,0 +1,35 @@
+import { generateTOTP } from '@epic-web/totp'
+import { createUser, createVerification } from '#tests/db-utils.ts'
+import { test, expect } from '#tests/test-extend.ts'
+
+test('authenticates using two-factor authentication', async ({
+ navigate,
+ page,
+}) => {
+ // Create a test user and enable 2FA for them directly in the database.
+ await using user = await createUser()
+ const totp = await generateTOTP()
+ await using _ = await createVerification({
+ totp,
+ userId: user.id,
+ })
+
+ // Log in as the created user.
+ await navigate('/login')
+
+ await page.getByLabel('Username').fill(user.username)
+ await page.getByLabel('Password').fill(user.password)
+ await page.getByRole('button', { name: 'Log in' }).click()
+
+ await expect(
+ page.getByRole('heading', { name: 'Check your 2FA app' }),
+ ).toBeVisible()
+
+ await page
+ .getByRole('textbox', { name: /code/i })
+ .fill((await generateTOTP(totp)).otp)
+
+ await page.getByRole('button', { name: 'Submit' }).click()
+
+ await expect(page.getByRole('link', { name: user.name! })).toBeVisible()
+})
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/setup/custom-matchers.ts b/exercises/02.authentication/02.solution.2fa/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/setup/custom-matchers.ts
rename to exercises/02.authentication/02.solution.2fa/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/setup/db-setup.ts b/exercises/02.authentication/02.solution.2fa/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/setup/db-setup.ts
rename to exercises/02.authentication/02.solution.2fa/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/setup/global-setup.ts b/exercises/02.authentication/02.solution.2fa/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/setup/global-setup.ts
rename to exercises/02.authentication/02.solution.2fa/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/setup/setup-test-env.ts b/exercises/02.authentication/02.solution.2fa/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/setup/setup-test-env.ts
rename to exercises/02.authentication/02.solution.2fa/tests/setup/setup-test-env.ts
diff --git a/exercises/03.guides/02.solution.test-annotations/tests/test-extend.ts b/exercises/02.authentication/02.solution.2fa/tests/test-extend.ts
similarity index 95%
rename from exercises/03.guides/02.solution.test-annotations/tests/test-extend.ts
rename to exercises/02.authentication/02.solution.2fa/tests/test-extend.ts
index 8b8eed1..a51b50d 100644
--- a/exercises/03.guides/02.solution.test-annotations/tests/test-extend.ts
+++ b/exercises/02.authentication/02.solution.2fa/tests/test-extend.ts
@@ -7,7 +7,7 @@ import {
import { href, type Register } from 'react-router'
import { getPasswordHash } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
-import { createUser } from '#tests/db-utils'
+import { generateUserInfo } from '#tests/db-utils'
interface Fixtures {
navigate: (
@@ -20,7 +20,7 @@ const user = definePersona('user', {
async createSession({ page }) {
const user = await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
roles: { connect: { name: 'user' } },
password: { create: { hash: await getPasswordHash('supersecret') } },
},
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/utils.ts b/exercises/02.authentication/02.solution.2fa/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/utils.ts
rename to exercises/02.authentication/02.solution.2fa/tests/utils.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tsconfig.json b/exercises/02.authentication/02.solution.2fa/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tsconfig.json
rename to exercises/02.authentication/02.solution.2fa/tsconfig.json
diff --git a/exercises/02.test-setup/03.solution.authentication/types/deps.d.ts b/exercises/02.authentication/02.solution.2fa/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/types/deps.d.ts
rename to exercises/02.authentication/02.solution.2fa/types/deps.d.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/types/env.env.d.ts b/exercises/02.authentication/02.solution.2fa/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/types/env.env.d.ts
rename to exercises/02.authentication/02.solution.2fa/types/env.env.d.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/types/icon-name.d.ts b/exercises/02.authentication/02.solution.2fa/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/types/icon-name.d.ts
rename to exercises/02.authentication/02.solution.2fa/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/types/reset.d.ts b/exercises/02.authentication/02.solution.2fa/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/types/reset.d.ts
rename to exercises/02.authentication/02.solution.2fa/types/reset.d.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/vite.config.ts b/exercises/02.authentication/02.solution.2fa/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/vite.config.ts
rename to exercises/02.authentication/02.solution.2fa/vite.config.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.env b/exercises/02.authentication/03.solution.passkeys/.env
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.env
rename to exercises/02.authentication/03.solution.passkeys/.env
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.env.example b/exercises/02.authentication/03.solution.passkeys/.env.example
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.env.example
rename to exercises/02.authentication/03.solution.passkeys/.env.example
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.gitignore b/exercises/02.authentication/03.solution.passkeys/.gitignore
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.gitignore
rename to exercises/02.authentication/03.solution.passkeys/.gitignore
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.npmrc b/exercises/02.authentication/03.solution.passkeys/.npmrc
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.npmrc
rename to exercises/02.authentication/03.solution.passkeys/.npmrc
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.prettierignore b/exercises/02.authentication/03.solution.passkeys/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.prettierignore
rename to exercises/02.authentication/03.solution.passkeys/.prettierignore
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.vscode/extensions.json b/exercises/02.authentication/03.solution.passkeys/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.vscode/extensions.json
rename to exercises/02.authentication/03.solution.passkeys/.vscode/extensions.json
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.vscode/remix.code-snippets b/exercises/02.authentication/03.solution.passkeys/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.vscode/remix.code-snippets
rename to exercises/02.authentication/03.solution.passkeys/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/04.problem.api-mocking/.vscode/settings.json b/exercises/02.authentication/03.solution.passkeys/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/.vscode/settings.json
rename to exercises/02.authentication/03.solution.passkeys/.vscode/settings.json
diff --git a/exercises/02.authentication/03.solution.passkeys/README.mdx b/exercises/02.authentication/03.solution.passkeys/README.mdx
new file mode 100644
index 0000000..a13a75f
--- /dev/null
+++ b/exercises/02.authentication/03.solution.passkeys/README.mdx
@@ -0,0 +1 @@
+# Passkeys
\ No newline at end of file
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/assets/favicons/apple-touch-icon.png b/exercises/02.authentication/03.solution.passkeys/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/assets/favicons/apple-touch-icon.png
rename to exercises/02.authentication/03.solution.passkeys/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/assets/favicons/favicon.svg b/exercises/02.authentication/03.solution.passkeys/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/assets/favicons/favicon.svg
rename to exercises/02.authentication/03.solution.passkeys/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/error-boundary.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/error-boundary.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/floating-toolbar.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/floating-toolbar.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/components/forms.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/components/forms.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/forms.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/progress-bar.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/progress-bar.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/search-bar.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/search-bar.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/spacer.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/spacer.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/toaster.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/toaster.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/README.md b/exercises/02.authentication/03.solution.passkeys/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/README.md
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/README.md
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/button.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/button.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/checkbox.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/checkbox.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/dropdown-menu.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/dropdown-menu.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/icon.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/icon.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/input-otp.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/input-otp.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/input.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/input.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/label.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/label.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/sonner.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/sonner.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/status-button.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/status-button.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/textarea.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/textarea.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/ui/tooltip.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/ui/tooltip.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/components/user-dropdown.tsx b/exercises/02.authentication/03.solution.passkeys/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/components/user-dropdown.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/entry.client.tsx b/exercises/02.authentication/03.solution.passkeys/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/entry.client.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/entry.client.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/entry.server.tsx b/exercises/02.authentication/03.solution.passkeys/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/entry.server.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/entry.server.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/root.tsx b/exercises/02.authentication/03.solution.passkeys/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/root.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/root.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes.ts b/exercises/02.authentication/03.solution.passkeys/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/$.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/$.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/$.tsx
diff --git a/exercises/04.debugging/03.solution.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 97%
rename from exercises/04.debugging/03.solution.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth.$provider.callback.test.ts
index 643e453..3765dd7 100644
--- a/exercises/04.debugging/03.solution.live-debugging/app/routes/_auth+/auth.$provider.callback.test.ts
+++ b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth.$provider.callback.test.ts
@@ -9,7 +9,7 @@ import { GITHUB_PROVIDER_NAME } from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { generateTOTP } from '#app/utils/totp.server.ts'
-import { createUser } from '#tests/db-utils.ts'
+import { generateUserInfo } from '#tests/db-utils.ts'
import { insertGitHubUser, deleteGitHubUsers } from '#tests/mocks/github.ts'
import { server } from '#tests/mocks/index.ts'
import { consoleError } from '#tests/setup/setup-test-env.ts'
@@ -109,7 +109,7 @@ test(`when a user is logged in and has already connected, it doesn't do anything
test('when a user exists with the same email, create connection and make session', async () => {
const githubUser = await insertGitHubUser()
const email = githubUser.primaryEmail.toLowerCase()
- const { userId } = await setupUser({ ...createUser(), email })
+ const { userId } = await setupUser({ ...generateUserInfo(), email })
const request = await setupRequest({ code: githubUser.code })
const response = await loader({ request, params: PARAMS, context: {} })
@@ -141,7 +141,7 @@ test('gives an error if the account is already connected to another user', async
const githubUser = await insertGitHubUser()
await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
connections: {
create: {
providerName: GITHUB_PROVIDER_NAME,
@@ -245,7 +245,7 @@ async function setupRequest({
return request
}
-async function setupUser(userData = createUser()) {
+async function setupUser(userData = generateUserInfo()) {
const session = await prisma.session.create({
data: {
expirationDate: getSessionExpirationDate(),
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth.$provider.callback.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth_.$provider.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth_.$provider.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/forgot-password.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/forgot-password.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/login.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/login.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/login.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/login.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/logout.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/logout.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/reset-password.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/reset-password.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/reset-password.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/reset-password.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/signup.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/signup.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/verify.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/verify.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/verify.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/verify.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/authentication.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/registration.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/about.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/about.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/index.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/index.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/docker.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/docker.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/eslint.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/eslint.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/faker.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/faker.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/fly.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/fly.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/github.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/github.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/logos.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/logos.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/msw.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/msw.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/playwright.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/playwright.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/prettier.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/prettier.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/prisma.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/prisma.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/radix.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/radix.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/react-email.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/react-email.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/remix.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/remix.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/resend.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/resend.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/sentry.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/sentry.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/sqlite.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/stars.jpg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/stars.jpg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/tailwind.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/testing-library.png b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/testing-library.png
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/typescript.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/typescript.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/vitest.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/vitest.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/zod.svg b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/logos/zod.svg
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/privacy.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/privacy.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/support.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/support.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/tos.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_marketing+/tos.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_seo+/robots[.]txt.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_seo+/robots[.]txt.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_seo+/sitemap[.]xml.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.server.ts b/exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/me.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/me.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/me.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/download-user-data.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/download-user-data.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/healthcheck.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/healthcheck.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/images.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/images.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/theme-switch.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/resources+/theme-switch.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.change-email.server.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.change-email.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.change-email.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.connections.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.connections.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.index.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.index.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.passkeys.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.passkeys.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.password.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.password.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.password_.create.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.password_.create.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.photo.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.photo.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.index.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/04.debugging/03.solution.live-debugging/app/routes/users+/$username.test.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username.test.tsx
similarity index 93%
rename from exercises/04.debugging/03.solution.live-debugging/app/routes/users+/$username.test.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username.test.tsx
index b0784bd..0884a24 100644
--- a/exercises/04.debugging/03.solution.live-debugging/app/routes/users+/$username.test.tsx
+++ b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username.test.tsx
@@ -10,7 +10,7 @@ import { loader as rootLoader } from '#app/root.tsx'
import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { authSessionStorage } from '#app/utils/session.server.ts'
-import { createUser, getUserImages } from '#tests/db-utils.ts'
+import { generateUserInfo, getUserImages } from '#tests/db-utils.ts'
import { default as UsernameRoute, loader } from './$username.tsx'
test('The user profile when not logged in as self', async () => {
@@ -19,7 +19,7 @@ test('The user profile when not logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const App = createRoutesStub([
{
@@ -44,7 +44,7 @@ test('The user profile when logged in as self', async () => {
userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
const user = await prisma.user.create({
select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
+ data: { ...generateUserInfo(), image: { create: userImage } },
})
const session = await prisma.session.create({
select: { id: true },
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/__note-editor.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.index.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.new.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username_+/notes.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/index.tsx b/exercises/02.authentication/03.solution.passkeys/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/index.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/styles/tailwind.css b/exercises/02.authentication/03.solution.passkeys/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/styles/tailwind.css
rename to exercises/02.authentication/03.solution.passkeys/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/auth.server.test.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/auth.server.test.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/auth.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/auth.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/cache.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/cache.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/client-hints.tsx b/exercises/02.authentication/03.solution.passkeys/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/client-hints.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/connections.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/connections.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/connections.tsx b/exercises/02.authentication/03.solution.passkeys/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/connections.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/db.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/db.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/email.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/email.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/env.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/env.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/headers.server.test.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/headers.server.test.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/headers.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/headers.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/honeypot.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/honeypot.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/litefs.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/litefs.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.error-message.test.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.error-message.test.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.tsx b/exercises/02.authentication/03.solution.passkeys/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.use-double-check.test.tsx b/exercises/02.authentication/03.solution.passkeys/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/misc.use-double-check.test.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/monitoring.client.tsx b/exercises/02.authentication/03.solution.passkeys/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/monitoring.client.tsx
rename to exercises/02.authentication/03.solution.passkeys/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/nonce-provider.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/nonce-provider.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/permissions.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/permissions.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/constants.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/constants.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/github.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/github.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/provider.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/providers/provider.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/redirect-cookie.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/redirect-cookie.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/request-info.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/request-info.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/session.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/session.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/storage.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/storage.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/theme.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/theme.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/timing.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/timing.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/toast.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/toast.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/totp.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/totp.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/user-validation.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/user-validation.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/user.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/user.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/user.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/utils/verification.server.ts b/exercises/02.authentication/03.solution.passkeys/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/utils/verification.server.ts
rename to exercises/02.authentication/03.solution.passkeys/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/components.json b/exercises/02.authentication/03.solution.passkeys/components.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/components.json
rename to exercises/02.authentication/03.solution.passkeys/components.json
diff --git a/exercises/02.test-setup/04.problem.api-mocking/eslint.config.js b/exercises/02.authentication/03.solution.passkeys/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/eslint.config.js
rename to exercises/02.authentication/03.solution.passkeys/eslint.config.js
diff --git a/exercises/02.test-setup/04.problem.api-mocking/fly.toml b/exercises/02.authentication/03.solution.passkeys/fly.toml
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/fly.toml
rename to exercises/02.authentication/03.solution.passkeys/fly.toml
diff --git a/exercises/02.test-setup/04.problem.api-mocking/index.js b/exercises/02.authentication/03.solution.passkeys/index.js
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/index.js
rename to exercises/02.authentication/03.solution.passkeys/index.js
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/Dockerfile b/exercises/02.authentication/03.solution.passkeys/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/Dockerfile
rename to exercises/02.authentication/03.solution.passkeys/other/Dockerfile
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/Dockerfile.dockerignore b/exercises/02.authentication/03.solution.passkeys/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/Dockerfile.dockerignore
rename to exercises/02.authentication/03.solution.passkeys/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/README.md b/exercises/02.authentication/03.solution.passkeys/other/README.md
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/README.md
rename to exercises/02.authentication/03.solution.passkeys/other/README.md
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/build-server.ts b/exercises/02.authentication/03.solution.passkeys/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/build-server.ts
rename to exercises/02.authentication/03.solution.passkeys/other/build-server.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/litefs.yml b/exercises/02.authentication/03.solution.passkeys/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/litefs.yml
rename to exercises/02.authentication/03.solution.passkeys/other/litefs.yml
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/sly/sly.json b/exercises/02.authentication/03.solution.passkeys/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/sly/sly.json
rename to exercises/02.authentication/03.solution.passkeys/other/sly/sly.json
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/sly/transform-icon.ts b/exercises/02.authentication/03.solution.passkeys/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/sly/transform-icon.ts
rename to exercises/02.authentication/03.solution.passkeys/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/README.md b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/README.md
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/arrow-left.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/arrow-left.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/arrow-right.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/arrow-right.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/avatar.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/avatar.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/camera.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/camera.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/check.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/check.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/clock.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/clock.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/cross-1.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/cross-1.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/dots-horizontal.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/dots-horizontal.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/download.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/download.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/envelope-closed.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/envelope-closed.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/exit.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/exit.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/file-text.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/file-text.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/github-logo.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/github-logo.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/laptop.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/laptop.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/link-2.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/link-2.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/lock-closed.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/lock-closed.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/lock-open-1.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/lock-open-1.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/magnifying-glass.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/magnifying-glass.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/moon.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/moon.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/passkey.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/passkey.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/pencil-1.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/pencil-1.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/pencil-2.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/pencil-2.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/plus.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/plus.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/question-mark-circled.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/question-mark-circled.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/reset.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/reset.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/sun.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/sun.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/trash.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/trash.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/update.svg b/exercises/02.authentication/03.solution.passkeys/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/other/svg-icons/update.svg
rename to exercises/02.authentication/03.solution.passkeys/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/04.problem.api-mocking/package-lock.json b/exercises/02.authentication/03.solution.passkeys/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/package-lock.json
rename to exercises/02.authentication/03.solution.passkeys/package-lock.json
diff --git a/exercises/02.test-setup/03.solution.authentication/package.json b/exercises/02.authentication/03.solution.passkeys/package.json
similarity index 98%
rename from exercises/02.test-setup/03.solution.authentication/package.json
rename to exercises/02.authentication/03.solution.passkeys/package.json
index a9eed9a..f893586 100644
--- a/exercises/02.test-setup/03.solution.authentication/package.json
+++ b/exercises/02.authentication/03.solution.passkeys/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_03.solution.authentication",
+ "name": "exercises_02.authentication_03.solution.passkeys",
"private": true,
"sideEffects": false,
"type": "module",
@@ -151,6 +151,7 @@
"prettier-plugin-tailwindcss": "^0.6.11",
"react-router-devtools": "^5.0.5",
"remix-flat-routes": "^0.8.5",
+ "test-passkey": "^1.0.1",
"tsx": "^4.19.4",
"tw-animate-css": "^1.2.9",
"typescript": "^5.8.3",
diff --git a/exercises/02.test-setup/04.problem.api-mocking/playwright.config.ts b/exercises/02.authentication/03.solution.passkeys/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/playwright.config.ts
rename to exercises/02.authentication/03.solution.passkeys/playwright.config.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/prisma/migrations/20250221233640_init/migration.sql b/exercises/02.authentication/03.solution.passkeys/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/02.authentication/03.solution.passkeys/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/04.problem.api-mocking/prisma/migrations/migration_lock.toml b/exercises/02.authentication/03.solution.passkeys/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/prisma/migrations/migration_lock.toml
rename to exercises/02.authentication/03.solution.passkeys/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/04.problem.api-mocking/prisma/schema.prisma b/exercises/02.authentication/03.solution.passkeys/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/prisma/schema.prisma
rename to exercises/02.authentication/03.solution.passkeys/prisma/schema.prisma
diff --git a/exercises/04.debugging/03.solution.live-debugging/prisma/seed.ts b/exercises/02.authentication/03.solution.passkeys/prisma/seed.ts
similarity index 99%
rename from exercises/04.debugging/03.solution.live-debugging/prisma/seed.ts
rename to exercises/02.authentication/03.solution.passkeys/prisma/seed.ts
index 8454353..521e1d5 100644
--- a/exercises/04.debugging/03.solution.live-debugging/prisma/seed.ts
+++ b/exercises/02.authentication/03.solution.passkeys/prisma/seed.ts
@@ -3,7 +3,7 @@ import { prisma } from '#app/utils/db.server.ts'
import { MOCK_CODE_GITHUB } from '#app/utils/providers/constants'
import {
createPassword,
- createUser,
+ generateUserInfo,
getNoteImages,
getUserImages,
} from '#tests/db-utils.ts'
@@ -19,7 +19,7 @@ async function seed() {
const userImages = await getUserImages()
for (let index = 0; index < totalUsers; index++) {
- const userData = createUser()
+ const userData = generateUserInfo()
const user = await prisma.user.create({
select: { id: true },
data: {
diff --git a/exercises/02.test-setup/04.problem.api-mocking/prisma/sql/searchUsers.sql b/exercises/02.authentication/03.solution.passkeys/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/prisma/sql/searchUsers.sql
rename to exercises/02.authentication/03.solution.passkeys/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/favicon.ico b/exercises/02.authentication/03.solution.passkeys/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/favicon.ico
rename to exercises/02.authentication/03.solution.passkeys/public/favicon.ico
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/favicons/README.md b/exercises/02.authentication/03.solution.passkeys/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/favicons/README.md
rename to exercises/02.authentication/03.solution.passkeys/public/favicons/README.md
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/favicons/android-chrome-192x192.png b/exercises/02.authentication/03.solution.passkeys/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/favicons/android-chrome-192x192.png
rename to exercises/02.authentication/03.solution.passkeys/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/favicons/android-chrome-512x512.png b/exercises/02.authentication/03.solution.passkeys/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/favicons/android-chrome-512x512.png
rename to exercises/02.authentication/03.solution.passkeys/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/img/user.png b/exercises/02.authentication/03.solution.passkeys/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/img/user.png
rename to exercises/02.authentication/03.solution.passkeys/public/img/user.png
diff --git a/exercises/02.test-setup/04.problem.api-mocking/public/site.webmanifest b/exercises/02.authentication/03.solution.passkeys/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/public/site.webmanifest
rename to exercises/02.authentication/03.solution.passkeys/public/site.webmanifest
diff --git a/exercises/02.test-setup/04.problem.api-mocking/react-router.config.ts b/exercises/02.authentication/03.solution.passkeys/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/react-router.config.ts
rename to exercises/02.authentication/03.solution.passkeys/react-router.config.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/server/dev-server.js b/exercises/02.authentication/03.solution.passkeys/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/server/dev-server.js
rename to exercises/02.authentication/03.solution.passkeys/server/dev-server.js
diff --git a/exercises/02.test-setup/04.problem.api-mocking/server/index.ts b/exercises/02.authentication/03.solution.passkeys/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/server/index.ts
rename to exercises/02.authentication/03.solution.passkeys/server/index.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/server/utils/monitoring.ts b/exercises/02.authentication/03.solution.passkeys/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/server/utils/monitoring.ts
rename to exercises/02.authentication/03.solution.passkeys/server/utils/monitoring.ts
diff --git a/exercises/04.debugging/02.problem.trace-viewer/tests/db-utils.ts b/exercises/02.authentication/03.solution.passkeys/tests/db-utils.ts
similarity index 66%
rename from exercises/04.debugging/02.problem.trace-viewer/tests/db-utils.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/db-utils.ts
index f701a8a..62543fe 100644
--- a/exercises/04.debugging/02.problem.trace-viewer/tests/db-utils.ts
+++ b/exercises/02.authentication/03.solution.passkeys/tests/db-utils.ts
@@ -1,10 +1,12 @@
import { faker } from '@faker-js/faker'
import bcrypt from 'bcryptjs'
import { UniqueEnforcer } from 'enforce-unique'
+import { getPasswordHash } from '#app/utils/auth.server.ts'
+import { prisma } from '#app/utils/db.server.ts'
const uniqueUsernameEnforcer = new UniqueEnforcer()
-export function createUser() {
+export function generateUserInfo() {
const firstName = faker.person.firstName()
const lastName = faker.person.lastName()
@@ -22,6 +24,7 @@ export function createUser() {
.slice(0, 20)
.toLowerCase()
.replace(/[^a-z0-9_]/g, '_')
+
return {
username,
name: `${firstName} ${lastName}`,
@@ -29,6 +32,59 @@ export function createUser() {
}
}
+export async function createUser() {
+ const userInfo = generateUserInfo()
+ const password = 'supersecret'
+ const user = await prisma.user.create({
+ data: {
+ ...userInfo,
+ password: { create: { hash: await getPasswordHash(password) } },
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.user.deleteMany({
+ where: { id: user.id },
+ })
+ },
+ ...user,
+ password,
+ }
+}
+
+export async function createPasskey(input: {
+ id: string
+ userId: string
+ aaguid: string
+ publicKey: Uint8Array
+ counter?: number
+}) {
+ const passkey = await prisma.passkey.create({
+ data: {
+ id: input.id,
+ aaguid: input.aaguid,
+ userId: input.userId,
+ publicKey: input.publicKey,
+ backedUp: false,
+ webauthnUserId: input.userId,
+ deviceType: 'singleDevice',
+ counter: input.counter || 0,
+ },
+ })
+
+ return {
+ async [Symbol.asyncDispose]() {
+ await prisma.passkey.deleteMany({
+ where: {
+ id: passkey.id,
+ },
+ })
+ },
+ ...passkey,
+ }
+}
+
export function createPassword(password: string = faker.internet.password()) {
return {
hash: bcrypt.hashSync(password, 10),
diff --git a/exercises/02.authentication/03.solution.passkeys/tests/e2e/authentication-passkeys.test.ts b/exercises/02.authentication/03.solution.passkeys/tests/e2e/authentication-passkeys.test.ts
new file mode 100644
index 0000000..d9ff8ca
--- /dev/null
+++ b/exercises/02.authentication/03.solution.passkeys/tests/e2e/authentication-passkeys.test.ts
@@ -0,0 +1,83 @@
+import { type Page } from '@playwright/test'
+import { createTestPasskey } from 'test-passkey'
+import { createPasskey, createUser } from '#tests/db-utils.ts'
+import { test, expect } from '#tests/test-extend.ts'
+
+async function createWebAuthnClient(page: Page) {
+ const client = await page.context().newCDPSession(page)
+ await client.send('WebAuthn.enable')
+
+ const result = await client.send('WebAuthn.addVirtualAuthenticator', {
+ options: {
+ protocol: 'ctap2',
+ transport: 'internal',
+ hasResidentKey: true,
+ hasUserVerification: true,
+ isUserVerified: true,
+ // Authenticator will automatically respond to the next prompt in the browser.
+ automaticPresenceSimulation: true,
+ },
+ })
+
+ return {
+ client,
+ authenticatorId: result.authenticatorId,
+ }
+}
+
+test('authenticates using an existing passkey', async ({ navigate, page }) => {
+ await navigate('/login')
+
+ // Create a test passkey.
+ const passkey = createTestPasskey({
+ rpId: new URL(page.url()).hostname,
+ })
+
+ // Add the passkey to the server.
+ await using user = await createUser()
+ await using _ = await createPasskey({
+ id: passkey.credential.credentialId,
+ aaguid: passkey.credential.aaguid || '',
+ publicKey: passkey.publicKey,
+ userId: user.id,
+ counter: passkey.credential.signCount,
+ })
+
+ // Add the passkey to the browser.
+ const { client, authenticatorId } = await createWebAuthnClient(page)
+ await client.send('WebAuthn.addCredential', {
+ authenticatorId,
+ credential: {
+ ...passkey.credential,
+ isResidentCredential: true,
+ userName: user.username,
+ userHandle: btoa(user.id),
+ userDisplayName: user.name ?? user.email,
+ },
+ })
+
+ await page.getByRole('button', { name: 'Login with a passkey' }).click()
+
+ await expect(page.getByText(user.name!)).toBeVisible()
+})
+
+test('displays an error when authenticating via a passkey fails', async ({
+ navigate,
+ page,
+}) => {
+ await navigate('/login')
+
+ const { client, authenticatorId } = await createWebAuthnClient(page)
+ await client.send('WebAuthn.setUserVerified', {
+ authenticatorId,
+ isUserVerified: false,
+ })
+
+ await page.getByRole('button', { name: 'Login with a passkey' }).click()
+
+ await expect(
+ page.getByText(
+ 'Failed to authenticate with passkey: The operation either timed out or was not allowed',
+ ),
+ ).toBeVisible()
+})
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/setup/custom-matchers.ts b/exercises/02.authentication/03.solution.passkeys/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/setup/custom-matchers.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/setup/db-setup.ts b/exercises/02.authentication/03.solution.passkeys/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/setup/db-setup.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/setup/global-setup.ts b/exercises/02.authentication/03.solution.passkeys/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/setup/global-setup.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/setup/setup-test-env.ts b/exercises/02.authentication/03.solution.passkeys/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/setup/setup-test-env.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/setup/setup-test-env.ts
diff --git a/exercises/04.debugging/03.solution.live-debugging/tests/test-extend.ts b/exercises/02.authentication/03.solution.passkeys/tests/test-extend.ts
similarity index 80%
rename from exercises/04.debugging/03.solution.live-debugging/tests/test-extend.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/test-extend.ts
index ce8099b..a51b50d 100644
--- a/exercises/04.debugging/03.solution.live-debugging/tests/test-extend.ts
+++ b/exercises/02.authentication/03.solution.passkeys/tests/test-extend.ts
@@ -1,6 +1,4 @@
-import { createNetworkFixture, type NetworkFixture } from '@msw/playwright'
import { test as testBase, expect } from '@playwright/test'
-import { http, HttpResponse } from 'msw'
import {
definePersona,
combinePersonas,
@@ -9,21 +7,20 @@ import {
import { href, type Register } from 'react-router'
import { getPasswordHash } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
-import { createUser } from '#tests/db-utils'
+import { generateUserInfo } from '#tests/db-utils'
interface Fixtures {
navigate: (
...args: Parameters>
) => Promise
authenticate: AuthenticateFunction<[typeof user]>
- network: NetworkFixture
}
const user = definePersona('user', {
async createSession({ page }) {
const user = await prisma.user.create({
data: {
- ...createUser(),
+ ...generateUserInfo(),
roles: { connect: { name: 'user' } },
password: { create: { hash: await getPasswordHash('supersecret') } },
},
@@ -55,13 +52,6 @@ export const test = testBase.extend({
})
},
authenticate: combinePersonas(user),
- network: createNetworkFixture({
- initialHandlers: [
- http.get('https://assets.onedollarstats.com/*', () => {
- return new HttpResponse()
- }),
- ],
- }),
})
export { expect }
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/utils.ts b/exercises/02.authentication/03.solution.passkeys/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/utils.ts
rename to exercises/02.authentication/03.solution.passkeys/tests/utils.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tsconfig.json b/exercises/02.authentication/03.solution.passkeys/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tsconfig.json
rename to exercises/02.authentication/03.solution.passkeys/tsconfig.json
diff --git a/exercises/02.test-setup/04.problem.api-mocking/types/deps.d.ts b/exercises/02.authentication/03.solution.passkeys/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/types/deps.d.ts
rename to exercises/02.authentication/03.solution.passkeys/types/deps.d.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/types/env.env.d.ts b/exercises/02.authentication/03.solution.passkeys/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/types/env.env.d.ts
rename to exercises/02.authentication/03.solution.passkeys/types/env.env.d.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/types/icon-name.d.ts b/exercises/02.authentication/03.solution.passkeys/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/types/icon-name.d.ts
rename to exercises/02.authentication/03.solution.passkeys/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/types/reset.d.ts b/exercises/02.authentication/03.solution.passkeys/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/types/reset.d.ts
rename to exercises/02.authentication/03.solution.passkeys/types/reset.d.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/vite.config.ts b/exercises/02.authentication/03.solution.passkeys/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/vite.config.ts
rename to exercises/02.authentication/03.solution.passkeys/vite.config.ts
diff --git a/exercises/02.authentication/04.solution.third-party-providers/README.mdx b/exercises/02.authentication/04.solution.third-party-providers/README.mdx
new file mode 100644
index 0000000..2dca483
--- /dev/null
+++ b/exercises/02.authentication/04.solution.third-party-providers/README.mdx
@@ -0,0 +1,23 @@
+# Third-party providers
+
+- How to test authentication that uses a third-party provider, like GitHub (usually OAuth).
+
+## Approaches
+
+1. Test users. Create an actual user of your third-party server and use their credentials in tests.
+ - Pros:
+ - Actual user.
+ - Running OAuth fully.
+ - Cons:
+ - Rigid. Need different user states? Have to create different users.
+ - Brittle. Some providers dislike automation in general and might block your test user.
+1. **API mocking + test data**. Intercept the OAuth flow and respond with mocked data. Requires you to have a mock user, too.
+ - Pros:
+ - Full control. Tap into any user/OAuth state/behavior.
+ - Cons:
+ - OAuth never really runs (not a bad thing).
+ - Coupled to the provider. You MUST replicate the network flow + data structures used by the provider in real life. Great if they ship some SDKs or typedefs to help you out. Not so great if you have to type it by hand (risk getting stale).
+
+
+- https://github.com/epicweb-dev/epic-stack/blob/97135fcd7899cab299b402f36804b0d169e87d9d/tests/e2e/onboarding.test.ts#L197
+- https://github.com/epicweb-dev/epic-stack/blob/97135fcd7899cab299b402f36804b0d169e87d9d/tests/mocks/github.ts#L136
diff --git a/exercises/02.test-setup/03.problem.authentication/.cursor/rules/avoid-use-effect.mdc b/exercises/02.authentication/05.problem.protected-logic/.cursor/rules/avoid-use-effect.mdc
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.cursor/rules/avoid-use-effect.mdc
rename to exercises/02.authentication/05.problem.protected-logic/.cursor/rules/avoid-use-effect.mdc
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.env b/exercises/02.authentication/05.problem.protected-logic/.env
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.env
rename to exercises/02.authentication/05.problem.protected-logic/.env
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.env.example b/exercises/02.authentication/05.problem.protected-logic/.env.example
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.env.example
rename to exercises/02.authentication/05.problem.protected-logic/.env.example
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.gitignore b/exercises/02.authentication/05.problem.protected-logic/.gitignore
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.gitignore
rename to exercises/02.authentication/05.problem.protected-logic/.gitignore
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.npmrc b/exercises/02.authentication/05.problem.protected-logic/.npmrc
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.npmrc
rename to exercises/02.authentication/05.problem.protected-logic/.npmrc
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.prettierignore b/exercises/02.authentication/05.problem.protected-logic/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.prettierignore
rename to exercises/02.authentication/05.problem.protected-logic/.prettierignore
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.vscode/extensions.json b/exercises/02.authentication/05.problem.protected-logic/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.vscode/extensions.json
rename to exercises/02.authentication/05.problem.protected-logic/.vscode/extensions.json
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.vscode/remix.code-snippets b/exercises/02.authentication/05.problem.protected-logic/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.vscode/remix.code-snippets
rename to exercises/02.authentication/05.problem.protected-logic/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/04.solution.api-mocking/.vscode/settings.json b/exercises/02.authentication/05.problem.protected-logic/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/.vscode/settings.json
rename to exercises/02.authentication/05.problem.protected-logic/.vscode/settings.json
diff --git a/exercises/02.test-setup/03.problem.authentication/README.mdx b/exercises/02.authentication/05.problem.protected-logic/README.mdx
similarity index 90%
rename from exercises/02.test-setup/03.problem.authentication/README.mdx
rename to exercises/02.authentication/05.problem.protected-logic/README.mdx
index d28b90b..ec549ef 100644
--- a/exercises/02.test-setup/03.problem.authentication/README.mdx
+++ b/exercises/02.authentication/05.problem.protected-logic/README.mdx
@@ -1,4 +1,6 @@
-# Authentication
+# Protected logic
+
+- Testing the logic behind authentication (e.g. user creating notes).
## Your task
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/assets/favicons/apple-touch-icon.png b/exercises/02.authentication/05.problem.protected-logic/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/assets/favicons/apple-touch-icon.png
rename to exercises/02.authentication/05.problem.protected-logic/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/assets/favicons/favicon.svg b/exercises/02.authentication/05.problem.protected-logic/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/assets/favicons/favicon.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/error-boundary.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/error-boundary.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/floating-toolbar.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/floating-toolbar.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/forms.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/forms.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/forms.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/progress-bar.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/progress-bar.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/search-bar.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/search-bar.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/spacer.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/spacer.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/toaster.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/toaster.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/README.md b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/README.md
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/README.md
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/button.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/button.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/checkbox.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/checkbox.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/dropdown-menu.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/dropdown-menu.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/icon.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/icon.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/input-otp.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/input-otp.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/input.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/input.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/label.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/label.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/sonner.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/sonner.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/status-button.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/status-button.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/textarea.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/textarea.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/ui/tooltip.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/ui/tooltip.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/components/user-dropdown.tsx b/exercises/02.authentication/05.problem.protected-logic/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/components/user-dropdown.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/entry.client.tsx b/exercises/02.authentication/05.problem.protected-logic/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/entry.client.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/entry.client.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/entry.server.tsx b/exercises/02.authentication/05.problem.protected-logic/app/entry.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/entry.server.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/entry.server.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/root.tsx b/exercises/02.authentication/05.problem.protected-logic/app/root.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/root.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/root.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/$.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/$.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/$.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth.$provider.callback.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth_.$provider.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth_.$provider.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/forgot-password.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/forgot-password.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/login.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/login.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/login.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/login.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/logout.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/logout.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/reset-password.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/reset-password.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/reset-password.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/reset-password.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/signup.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/signup.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/verify.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/verify.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/verify.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/verify.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/authentication.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/registration.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/about.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/about.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/index.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/index.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/docker.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/docker.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/eslint.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/eslint.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/faker.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/faker.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/fly.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/fly.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/github.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/github.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/logos.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/logos.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/msw.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/msw.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/playwright.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/playwright.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/prettier.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/prettier.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/prisma.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/prisma.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/radix.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/radix.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/react-email.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/react-email.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/remix.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/remix.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/resend.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/resend.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/sentry.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/sentry.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/sqlite.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/stars.jpg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/stars.jpg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/tailwind.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/testing-library.png b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/testing-library.png
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/typescript.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/typescript.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/vitest.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/vitest.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/zod.svg b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/logos/zod.svg
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/privacy.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/privacy.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/support.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/support.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/tos.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_marketing+/tos.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_seo+/robots[.]txt.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_seo+/robots[.]txt.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_seo+/sitemap[.]xml.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/me.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/me.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/me.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/download-user-data.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/download-user-data.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/healthcheck.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/healthcheck.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/images.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/images.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/theme-switch.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/resources+/theme-switch.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.change-email.server.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.change-email.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.change-email.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.connections.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.connections.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.index.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.index.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.passkeys.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.passkeys.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.password.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.password.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.password_.create.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.password_.create.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.photo.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.photo.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.index.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username.test.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/app/routes/users+/$username.test.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username.test.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/__note-editor.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.index.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.new.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username_+/notes.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/index.tsx b/exercises/02.authentication/05.problem.protected-logic/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/index.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/styles/tailwind.css b/exercises/02.authentication/05.problem.protected-logic/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/styles/tailwind.css
rename to exercises/02.authentication/05.problem.protected-logic/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/auth.server.test.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/auth.server.test.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/auth.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/auth.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/cache.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/cache.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/client-hints.tsx b/exercises/02.authentication/05.problem.protected-logic/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/client-hints.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/connections.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/connections.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/connections.tsx b/exercises/02.authentication/05.problem.protected-logic/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/connections.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/db.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/db.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/email.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/email.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/env.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/env.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/headers.server.test.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/headers.server.test.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/headers.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/headers.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/honeypot.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/honeypot.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/litefs.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/litefs.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.error-message.test.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.error-message.test.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.tsx b/exercises/02.authentication/05.problem.protected-logic/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.use-double-check.test.tsx b/exercises/02.authentication/05.problem.protected-logic/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/misc.use-double-check.test.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/monitoring.client.tsx b/exercises/02.authentication/05.problem.protected-logic/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/monitoring.client.tsx
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/nonce-provider.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/nonce-provider.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/permissions.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/permissions.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/constants.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/constants.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/github.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/github.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/provider.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/providers/provider.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/redirect-cookie.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/redirect-cookie.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/request-info.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/request-info.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/session.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/session.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/storage.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/storage.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/theme.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/theme.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/timing.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/timing.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/toast.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/toast.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/totp.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/totp.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/user-validation.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/user-validation.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/user.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/user.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/user.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/utils/verification.server.ts b/exercises/02.authentication/05.problem.protected-logic/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/utils/verification.server.ts
rename to exercises/02.authentication/05.problem.protected-logic/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/components.json b/exercises/02.authentication/05.problem.protected-logic/components.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/components.json
rename to exercises/02.authentication/05.problem.protected-logic/components.json
diff --git a/exercises/02.test-setup/04.solution.api-mocking/eslint.config.js b/exercises/02.authentication/05.problem.protected-logic/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/eslint.config.js
rename to exercises/02.authentication/05.problem.protected-logic/eslint.config.js
diff --git a/exercises/02.test-setup/04.solution.api-mocking/fly.toml b/exercises/02.authentication/05.problem.protected-logic/fly.toml
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/fly.toml
rename to exercises/02.authentication/05.problem.protected-logic/fly.toml
diff --git a/exercises/02.test-setup/04.solution.api-mocking/index.js b/exercises/02.authentication/05.problem.protected-logic/index.js
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/index.js
rename to exercises/02.authentication/05.problem.protected-logic/index.js
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/Dockerfile b/exercises/02.authentication/05.problem.protected-logic/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/Dockerfile
rename to exercises/02.authentication/05.problem.protected-logic/other/Dockerfile
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/Dockerfile.dockerignore b/exercises/02.authentication/05.problem.protected-logic/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/Dockerfile.dockerignore
rename to exercises/02.authentication/05.problem.protected-logic/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/README.md b/exercises/02.authentication/05.problem.protected-logic/other/README.md
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/README.md
rename to exercises/02.authentication/05.problem.protected-logic/other/README.md
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/build-server.ts b/exercises/02.authentication/05.problem.protected-logic/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/build-server.ts
rename to exercises/02.authentication/05.problem.protected-logic/other/build-server.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/litefs.yml b/exercises/02.authentication/05.problem.protected-logic/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/litefs.yml
rename to exercises/02.authentication/05.problem.protected-logic/other/litefs.yml
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/sly/sly.json b/exercises/02.authentication/05.problem.protected-logic/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/sly/sly.json
rename to exercises/02.authentication/05.problem.protected-logic/other/sly/sly.json
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/sly/transform-icon.ts b/exercises/02.authentication/05.problem.protected-logic/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/sly/transform-icon.ts
rename to exercises/02.authentication/05.problem.protected-logic/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/README.md b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/README.md
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/arrow-left.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/arrow-left.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/arrow-right.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/arrow-right.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/avatar.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/avatar.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/camera.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/camera.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/check.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/check.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/clock.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/clock.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/cross-1.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/cross-1.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/dots-horizontal.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/dots-horizontal.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/download.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/download.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/envelope-closed.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/envelope-closed.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/exit.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/exit.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/file-text.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/file-text.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/github-logo.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/github-logo.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/laptop.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/laptop.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/link-2.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/link-2.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/lock-closed.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/lock-closed.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/lock-open-1.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/lock-open-1.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/magnifying-glass.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/magnifying-glass.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/moon.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/moon.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/passkey.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/passkey.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/pencil-1.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/pencil-1.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/pencil-2.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/pencil-2.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/plus.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/plus.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/question-mark-circled.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/question-mark-circled.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/reset.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/reset.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/sun.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/sun.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/trash.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/trash.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/update.svg b/exercises/02.authentication/05.problem.protected-logic/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/other/svg-icons/update.svg
rename to exercises/02.authentication/05.problem.protected-logic/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/04.solution.api-mocking/package-lock.json b/exercises/02.authentication/05.problem.protected-logic/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/package-lock.json
rename to exercises/02.authentication/05.problem.protected-logic/package-lock.json
diff --git a/exercises/02.test-setup/01.solution.custom-fixtures/package.json b/exercises/02.authentication/05.problem.protected-logic/package.json
similarity index 98%
rename from exercises/02.test-setup/01.solution.custom-fixtures/package.json
rename to exercises/02.authentication/05.problem.protected-logic/package.json
index f6809af..14943ac 100644
--- a/exercises/02.test-setup/01.solution.custom-fixtures/package.json
+++ b/exercises/02.authentication/05.problem.protected-logic/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_01.solution.custom-fixtures",
+ "name": "exercises_02.authentication_05.problem.protected-logic",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/02.test-setup/04.solution.api-mocking/playwright.config.ts b/exercises/02.authentication/05.problem.protected-logic/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/playwright.config.ts
rename to exercises/02.authentication/05.problem.protected-logic/playwright.config.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/prisma/migrations/20250221233640_init/migration.sql b/exercises/02.authentication/05.problem.protected-logic/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/02.authentication/05.problem.protected-logic/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/04.solution.api-mocking/prisma/migrations/migration_lock.toml b/exercises/02.authentication/05.problem.protected-logic/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/prisma/migrations/migration_lock.toml
rename to exercises/02.authentication/05.problem.protected-logic/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/04.solution.api-mocking/prisma/schema.prisma b/exercises/02.authentication/05.problem.protected-logic/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/prisma/schema.prisma
rename to exercises/02.authentication/05.problem.protected-logic/prisma/schema.prisma
diff --git a/exercises/02.test-setup/03.problem.authentication/prisma/seed.ts b/exercises/02.authentication/05.problem.protected-logic/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/prisma/seed.ts
rename to exercises/02.authentication/05.problem.protected-logic/prisma/seed.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/prisma/sql/searchUsers.sql b/exercises/02.authentication/05.problem.protected-logic/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/prisma/sql/searchUsers.sql
rename to exercises/02.authentication/05.problem.protected-logic/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/favicon.ico b/exercises/02.authentication/05.problem.protected-logic/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/favicon.ico
rename to exercises/02.authentication/05.problem.protected-logic/public/favicon.ico
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/favicons/README.md b/exercises/02.authentication/05.problem.protected-logic/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/favicons/README.md
rename to exercises/02.authentication/05.problem.protected-logic/public/favicons/README.md
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/favicons/android-chrome-192x192.png b/exercises/02.authentication/05.problem.protected-logic/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/favicons/android-chrome-192x192.png
rename to exercises/02.authentication/05.problem.protected-logic/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/favicons/android-chrome-512x512.png b/exercises/02.authentication/05.problem.protected-logic/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/favicons/android-chrome-512x512.png
rename to exercises/02.authentication/05.problem.protected-logic/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/img/user.png b/exercises/02.authentication/05.problem.protected-logic/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/img/user.png
rename to exercises/02.authentication/05.problem.protected-logic/public/img/user.png
diff --git a/exercises/02.test-setup/04.solution.api-mocking/public/site.webmanifest b/exercises/02.authentication/05.problem.protected-logic/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/public/site.webmanifest
rename to exercises/02.authentication/05.problem.protected-logic/public/site.webmanifest
diff --git a/exercises/02.test-setup/04.solution.api-mocking/react-router.config.ts b/exercises/02.authentication/05.problem.protected-logic/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/react-router.config.ts
rename to exercises/02.authentication/05.problem.protected-logic/react-router.config.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/server/dev-server.js b/exercises/02.authentication/05.problem.protected-logic/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/server/dev-server.js
rename to exercises/02.authentication/05.problem.protected-logic/server/dev-server.js
diff --git a/exercises/02.test-setup/04.solution.api-mocking/server/index.ts b/exercises/02.authentication/05.problem.protected-logic/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/server/index.ts
rename to exercises/02.authentication/05.problem.protected-logic/server/index.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/server/utils/monitoring.ts b/exercises/02.authentication/05.problem.protected-logic/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/server/utils/monitoring.ts
rename to exercises/02.authentication/05.problem.protected-logic/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/db-utils.ts b/exercises/02.authentication/05.problem.protected-logic/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/db-utils.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/db-utils.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/e2e/notes-create.test.ts b/exercises/02.authentication/05.problem.protected-logic/tests/e2e/notes-create.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/e2e/notes-create.test.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/e2e/notes-create.test.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/setup/custom-matchers.ts b/exercises/02.authentication/05.problem.protected-logic/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/setup/custom-matchers.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/setup/db-setup.ts b/exercises/02.authentication/05.problem.protected-logic/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/setup/db-setup.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/setup/global-setup.ts b/exercises/02.authentication/05.problem.protected-logic/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/setup/global-setup.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/setup/setup-test-env.ts b/exercises/02.authentication/05.problem.protected-logic/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/setup/setup-test-env.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/03.problem.authentication/tests/test-extend.ts b/exercises/02.authentication/05.problem.protected-logic/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/tests/test-extend.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/test-extend.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/utils.ts b/exercises/02.authentication/05.problem.protected-logic/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/utils.ts
rename to exercises/02.authentication/05.problem.protected-logic/tests/utils.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tsconfig.json b/exercises/02.authentication/05.problem.protected-logic/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tsconfig.json
rename to exercises/02.authentication/05.problem.protected-logic/tsconfig.json
diff --git a/exercises/02.test-setup/04.solution.api-mocking/types/deps.d.ts b/exercises/02.authentication/05.problem.protected-logic/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/types/deps.d.ts
rename to exercises/02.authentication/05.problem.protected-logic/types/deps.d.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/types/env.env.d.ts b/exercises/02.authentication/05.problem.protected-logic/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/types/env.env.d.ts
rename to exercises/02.authentication/05.problem.protected-logic/types/env.env.d.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/types/icon-name.d.ts b/exercises/02.authentication/05.problem.protected-logic/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/types/icon-name.d.ts
rename to exercises/02.authentication/05.problem.protected-logic/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/types/reset.d.ts b/exercises/02.authentication/05.problem.protected-logic/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/types/reset.d.ts
rename to exercises/02.authentication/05.problem.protected-logic/types/reset.d.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/vite.config.ts b/exercises/02.authentication/05.problem.protected-logic/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/vite.config.ts
rename to exercises/02.authentication/05.problem.protected-logic/vite.config.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/.env b/exercises/02.authentication/05.solution.protected-logic/.env
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.env
rename to exercises/02.authentication/05.solution.protected-logic/.env
diff --git a/exercises/02.test-setup/05.problem.test-data/.env.example b/exercises/02.authentication/05.solution.protected-logic/.env.example
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.env.example
rename to exercises/02.authentication/05.solution.protected-logic/.env.example
diff --git a/exercises/02.test-setup/05.problem.test-data/.gitignore b/exercises/02.authentication/05.solution.protected-logic/.gitignore
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.gitignore
rename to exercises/02.authentication/05.solution.protected-logic/.gitignore
diff --git a/exercises/02.test-setup/05.problem.test-data/.npmrc b/exercises/02.authentication/05.solution.protected-logic/.npmrc
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.npmrc
rename to exercises/02.authentication/05.solution.protected-logic/.npmrc
diff --git a/exercises/02.test-setup/05.problem.test-data/.prettierignore b/exercises/02.authentication/05.solution.protected-logic/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.prettierignore
rename to exercises/02.authentication/05.solution.protected-logic/.prettierignore
diff --git a/exercises/02.test-setup/05.problem.test-data/.vscode/extensions.json b/exercises/02.authentication/05.solution.protected-logic/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.vscode/extensions.json
rename to exercises/02.authentication/05.solution.protected-logic/.vscode/extensions.json
diff --git a/exercises/02.test-setup/05.problem.test-data/.vscode/remix.code-snippets b/exercises/02.authentication/05.solution.protected-logic/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.vscode/remix.code-snippets
rename to exercises/02.authentication/05.solution.protected-logic/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/05.problem.test-data/.vscode/settings.json b/exercises/02.authentication/05.solution.protected-logic/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/.vscode/settings.json
rename to exercises/02.authentication/05.solution.protected-logic/.vscode/settings.json
diff --git a/exercises/02.test-setup/03.solution.authentication/README.mdx b/exercises/02.authentication/05.solution.protected-logic/README.mdx
similarity index 86%
rename from exercises/02.test-setup/03.solution.authentication/README.mdx
rename to exercises/02.authentication/05.solution.protected-logic/README.mdx
index a03787c..f2db9c6 100644
--- a/exercises/02.test-setup/03.solution.authentication/README.mdx
+++ b/exercises/02.authentication/05.solution.protected-logic/README.mdx
@@ -1,4 +1,4 @@
-# Authentication
+# Protected logic
Good job! 👏
diff --git a/exercises/02.test-setup/05.problem.test-data/app/assets/favicons/apple-touch-icon.png b/exercises/02.authentication/05.solution.protected-logic/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/assets/favicons/apple-touch-icon.png
rename to exercises/02.authentication/05.solution.protected-logic/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/05.problem.test-data/app/assets/favicons/favicon.svg b/exercises/02.authentication/05.solution.protected-logic/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/assets/favicons/favicon.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/error-boundary.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/error-boundary.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/floating-toolbar.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/floating-toolbar.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/floating-toolbar.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/forms.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/forms.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/forms.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/forms.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/progress-bar.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/progress-bar.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/search-bar.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/search-bar.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/spacer.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/spacer.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/toaster.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/toaster.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/README.md b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/README.md
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/README.md
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/button.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/button.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/checkbox.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/checkbox.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/dropdown-menu.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/dropdown-menu.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/icon.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/icon.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/input-otp.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/input-otp.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/input.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/input.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/label.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/label.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/sonner.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/sonner.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/status-button.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/status-button.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/textarea.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/textarea.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/ui/tooltip.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/ui/tooltip.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/components/user-dropdown.tsx b/exercises/02.authentication/05.solution.protected-logic/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/components/user-dropdown.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/entry.client.tsx b/exercises/02.authentication/05.solution.protected-logic/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/entry.client.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/entry.client.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/entry.server.tsx b/exercises/02.authentication/05.solution.protected-logic/app/entry.server.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/entry.server.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/entry.server.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/root.tsx b/exercises/02.authentication/05.solution.protected-logic/app/root.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/root.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/root.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/$.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/$.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/$.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/auth.$provider.callback.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/auth_.$provider.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/auth_.$provider.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/forgot-password.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/forgot-password.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/login.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/login.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/login.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/login.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/logout.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/logout.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/reset-password.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/reset-password.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/reset-password.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/reset-password.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/signup.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/signup.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/verify.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/verify.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/verify.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/verify.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/authentication.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/registration.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/about.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/about.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/index.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/index.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/docker.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/docker.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/eslint.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/eslint.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/faker.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/faker.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/fly.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/fly.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/github.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/github.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/logos.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/logos.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/msw.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/msw.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/playwright.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/playwright.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/prettier.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/prettier.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/prisma.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/prisma.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/radix.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/radix.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/react-email.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/react-email.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/remix.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/remix.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/resend.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/resend.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/sentry.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/sentry.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/sqlite.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/stars.jpg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/stars.jpg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/tailwind.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/testing-library.png b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/testing-library.png
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/typescript.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/typescript.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/vitest.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/vitest.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/zod.svg b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/logos/zod.svg
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/privacy.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/privacy.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/support.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/support.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/tos.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_marketing+/tos.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_seo+/robots[.]txt.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_seo+/robots[.]txt.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/_seo+/sitemap[.]xml.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/me.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/me.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/me.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/resources+/download-user-data.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/resources+/download-user-data.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/resources+/healthcheck.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/resources+/healthcheck.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/resources+/images.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/resources+/images.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/resources+/theme-switch.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/resources+/theme-switch.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.change-email.server.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.change-email.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.change-email.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.connections.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.connections.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.index.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.index.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.passkeys.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.passkeys.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.password.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.password.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.password_.create.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.password_.create.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.photo.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.photo.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.index.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username.test.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/app/routes/users+/$username.test.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username.test.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/__note-editor.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.index.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.new.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/index.tsx b/exercises/02.authentication/05.solution.protected-logic/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/index.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/styles/tailwind.css b/exercises/02.authentication/05.solution.protected-logic/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/styles/tailwind.css
rename to exercises/02.authentication/05.solution.protected-logic/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/auth.server.test.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/auth.server.test.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/auth.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/auth.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/cache.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/cache.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/client-hints.tsx b/exercises/02.authentication/05.solution.protected-logic/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/client-hints.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/connections.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/connections.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/connections.tsx b/exercises/02.authentication/05.solution.protected-logic/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/connections.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/db.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/db.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/email.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/email.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/env.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/env.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/headers.server.test.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/headers.server.test.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/headers.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/headers.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/honeypot.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/honeypot.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/litefs.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/litefs.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/misc.error-message.test.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/misc.error-message.test.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/misc.tsx b/exercises/02.authentication/05.solution.protected-logic/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/misc.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/misc.use-double-check.test.tsx b/exercises/02.authentication/05.solution.protected-logic/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/misc.use-double-check.test.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/monitoring.client.tsx b/exercises/02.authentication/05.solution.protected-logic/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/monitoring.client.tsx
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/nonce-provider.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/nonce-provider.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/permissions.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/permissions.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/providers/constants.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/providers/constants.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/providers/github.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/providers/github.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/providers/provider.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/providers/provider.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/redirect-cookie.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/redirect-cookie.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/request-info.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/request-info.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/session.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/session.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/storage.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/storage.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/theme.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/theme.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/timing.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/timing.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/toast.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/toast.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/totp.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/totp.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/user-validation.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/user-validation.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/user.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/user.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/user.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/app/utils/verification.server.ts b/exercises/02.authentication/05.solution.protected-logic/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/utils/verification.server.ts
rename to exercises/02.authentication/05.solution.protected-logic/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/components.json b/exercises/02.authentication/05.solution.protected-logic/components.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/components.json
rename to exercises/02.authentication/05.solution.protected-logic/components.json
diff --git a/exercises/02.test-setup/05.problem.test-data/eslint.config.js b/exercises/02.authentication/05.solution.protected-logic/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/eslint.config.js
rename to exercises/02.authentication/05.solution.protected-logic/eslint.config.js
diff --git a/exercises/02.test-setup/05.problem.test-data/fly.toml b/exercises/02.authentication/05.solution.protected-logic/fly.toml
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/fly.toml
rename to exercises/02.authentication/05.solution.protected-logic/fly.toml
diff --git a/exercises/02.test-setup/05.problem.test-data/index.js b/exercises/02.authentication/05.solution.protected-logic/index.js
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/index.js
rename to exercises/02.authentication/05.solution.protected-logic/index.js
diff --git a/exercises/02.test-setup/05.problem.test-data/other/Dockerfile b/exercises/02.authentication/05.solution.protected-logic/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/Dockerfile
rename to exercises/02.authentication/05.solution.protected-logic/other/Dockerfile
diff --git a/exercises/02.test-setup/05.problem.test-data/other/Dockerfile.dockerignore b/exercises/02.authentication/05.solution.protected-logic/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/Dockerfile.dockerignore
rename to exercises/02.authentication/05.solution.protected-logic/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/05.problem.test-data/other/README.md b/exercises/02.authentication/05.solution.protected-logic/other/README.md
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/README.md
rename to exercises/02.authentication/05.solution.protected-logic/other/README.md
diff --git a/exercises/02.test-setup/05.problem.test-data/other/build-server.ts b/exercises/02.authentication/05.solution.protected-logic/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/build-server.ts
rename to exercises/02.authentication/05.solution.protected-logic/other/build-server.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/other/litefs.yml b/exercises/02.authentication/05.solution.protected-logic/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/litefs.yml
rename to exercises/02.authentication/05.solution.protected-logic/other/litefs.yml
diff --git a/exercises/02.test-setup/05.problem.test-data/other/sly/sly.json b/exercises/02.authentication/05.solution.protected-logic/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/sly/sly.json
rename to exercises/02.authentication/05.solution.protected-logic/other/sly/sly.json
diff --git a/exercises/02.test-setup/05.problem.test-data/other/sly/transform-icon.ts b/exercises/02.authentication/05.solution.protected-logic/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/sly/transform-icon.ts
rename to exercises/02.authentication/05.solution.protected-logic/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/README.md b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/README.md
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/arrow-left.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/arrow-left.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/arrow-right.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/arrow-right.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/avatar.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/avatar.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/camera.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/camera.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/check.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/check.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/clock.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/clock.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/cross-1.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/cross-1.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/dots-horizontal.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/dots-horizontal.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/download.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/download.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/envelope-closed.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/envelope-closed.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/exit.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/exit.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/file-text.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/file-text.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/github-logo.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/github-logo.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/laptop.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/laptop.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/link-2.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/link-2.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/lock-closed.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/lock-closed.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/lock-open-1.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/lock-open-1.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/magnifying-glass.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/magnifying-glass.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/moon.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/moon.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/passkey.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/passkey.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/pencil-1.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/pencil-1.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/pencil-2.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/pencil-2.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/plus.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/plus.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/question-mark-circled.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/question-mark-circled.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/reset.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/reset.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/sun.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/sun.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/trash.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/trash.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/other/svg-icons/update.svg b/exercises/02.authentication/05.solution.protected-logic/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/other/svg-icons/update.svg
rename to exercises/02.authentication/05.solution.protected-logic/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/05.problem.test-data/package-lock.json b/exercises/02.authentication/05.solution.protected-logic/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/package-lock.json
rename to exercises/02.authentication/05.solution.protected-logic/package-lock.json
diff --git a/exercises/02.authentication/05.solution.protected-logic/package.json b/exercises/02.authentication/05.solution.protected-logic/package.json
new file mode 100644
index 0000000..7c8ff5e
--- /dev/null
+++ b/exercises/02.authentication/05.solution.protected-logic/package.json
@@ -0,0 +1,171 @@
+{
+ "name": "exercises_02.authentication_05.solution.protected-logic",
+ "private": true,
+ "sideEffects": false,
+ "type": "module",
+ "imports": {
+ "#app/*": "./app/*",
+ "#tests/*": "./tests/*"
+ },
+ "scripts": {
+ "build": "run-s build:*",
+ "build:remix": "react-router build",
+ "build:server": "tsx ./other/build-server.ts",
+ "dev": "cross-env NODE_ENV=development MOCKS=true node ./server/dev-server.js",
+ "dev:no-mocks": "cross-env NODE_ENV=development node ./server/dev-server.js",
+ "format": "prettier --write .",
+ "lint": "eslint .",
+ "setup": "npm run build && prisma migrate deploy && prisma generate --sql && playwright install",
+ "start": "cross-env NODE_ENV=production node .",
+ "start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .",
+ "test": "npx playwright test",
+ "coverage": "vitest run --coverage",
+ "test:e2e": "npm run test:e2e:dev --silent",
+ "test:e2e:dev": "npx playwright test --ui",
+ "pretest:e2e:run": "npm run build",
+ "test:e2e:run": "npx cross-env CI=true npx playwright test",
+ "test:e2e:install": "npx playwright install --with-deps chromium",
+ "typecheck": "react-router typegen && tsc",
+ "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run",
+ "post:playground": "npx react-router typegen && prisma migrate deploy && prisma generate --sql"
+ },
+ "prettier": "@epic-web/config/prettier",
+ "eslintIgnore": [
+ "/node_modules",
+ "/build",
+ "/public/build",
+ "/playwright-report",
+ "/server-build"
+ ],
+ "dependencies": {
+ "@conform-to/react": "^1.5.0",
+ "@conform-to/zod": "^1.5.0",
+ "@epic-web/cachified": "^5.5.2",
+ "@epic-web/client-hints": "^1.3.5",
+ "@epic-web/invariant": "^1.0.0",
+ "@epic-web/remember": "^1.1.0",
+ "@epic-web/totp": "^4.0.1",
+ "@mjackson/form-data-parser": "^0.7.0",
+ "@mjackson/headers": "^0.10.0",
+ "@nasa-gcn/remix-seo": "^2.0.1",
+ "@nichtsam/helmet": "^0.3.1",
+ "@oslojs/crypto": "^1.0.1",
+ "@oslojs/encoding": "^1.1.0",
+ "@paralleldrive/cuid2": "^2.2.2",
+ "@prisma/client": "^6.7.0",
+ "@prisma/instrumentation": "^6.7.0",
+ "@radix-ui/react-checkbox": "^1.2.3",
+ "@radix-ui/react-dropdown-menu": "^2.1.12",
+ "@radix-ui/react-label": "^2.1.4",
+ "@radix-ui/react-slot": "^1.2.0",
+ "@radix-ui/react-toast": "^1.2.11",
+ "@radix-ui/react-tooltip": "^1.2.4",
+ "@react-email/components": "0.0.38",
+ "@react-router/express": "^7.5.3",
+ "@react-router/node": "^7.5.3",
+ "@react-router/remix-routes-option-adapter": "^7.5.3",
+ "@remix-run/server-runtime": "^2.16.5",
+ "@sentry/profiling-node": "^9.32.0",
+ "@sentry/react-router": "^9.32.0",
+ "@simplewebauthn/browser": "^13.1.0",
+ "@simplewebauthn/server": "^13.1.1",
+ "@tailwindcss/vite": "^4.1.5",
+ "@tusbar/cache-control": "1.0.2",
+ "address": "^2.0.3",
+ "bcryptjs": "^3.0.2",
+ "class-variance-authority": "^0.7.1",
+ "close-with-grace": "^2.2.0",
+ "clsx": "^2.1.1",
+ "compression": "^1.8.0",
+ "cookie": "^1.0.2",
+ "cross-env": "^7.0.3",
+ "date-fns": "^4.1.0",
+ "dotenv": "^16.5.0",
+ "execa": "^9.5.2",
+ "express": "^4.21.2",
+ "express-rate-limit": "^7.5.0",
+ "get-port": "^7.1.0",
+ "glob": "^11.0.2",
+ "input-otp": "^1.4.2",
+ "intl-parse-accept-language": "^1.0.0",
+ "isbot": "^5.1.27",
+ "litefs-js": "^2.0.2",
+ "lru-cache": "^11.1.0",
+ "mime-types": "^3.0.1",
+ "morgan": "^1.10.0",
+ "openimg": "^1.1.0",
+ "prisma": "^6.7.0",
+ "qrcode": "^1.5.4",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-router": "^7.5.3",
+ "remix-auth": "^4.2.0",
+ "remix-auth-github": "^3.0.2",
+ "remix-utils": "^8.5.0",
+ "set-cookie-parser": "^2.7.1",
+ "sharp": "^0.34.2",
+ "sonner": "^2.0.3",
+ "source-map-support": "^0.5.21",
+ "spin-delay": "^2.0.1",
+ "tailwind-merge": "^3.2.0",
+ "tailwindcss": "^4.1.5",
+ "vite-env-only": "^3.0.3",
+ "zod": "^3.24.4"
+ },
+ "devDependencies": {
+ "@epic-web/config": "^1.20.1",
+ "@faker-js/faker": "^9.7.0",
+ "@playwright/test": "^1.52.0",
+ "@react-router/dev": "^7.5.3",
+ "@sly-cli/sly": "^2.1.1",
+ "@testing-library/dom": "^10.4.0",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^14.6.1",
+ "@total-typescript/ts-reset": "^0.6.1",
+ "@types/compression": "^1.7.5",
+ "@types/eslint": "^9.6.1",
+ "@types/express": "^4.17.21",
+ "@types/fs-extra": "^11.0.4",
+ "@types/glob": "^8.1.0",
+ "@types/mime-types": "^2.1.4",
+ "@types/morgan": "^1.9.9",
+ "@types/node": "^22.15.3",
+ "@types/qrcode": "^1.5.5",
+ "@types/react": "^19.1.2",
+ "@types/react-dom": "^19.1.3",
+ "@types/set-cookie-parser": "^2.4.10",
+ "@types/source-map-support": "^0.5.10",
+ "@vitejs/plugin-react": "^4.4.1",
+ "@vitest/coverage-v8": "^3.1.3",
+ "enforce-unique": "^1.3.0",
+ "esbuild": "^0.25.3",
+ "eslint": "^9.26.0",
+ "fs-extra": "^11.3.0",
+ "jsdom": "^25.0.1",
+ "msw": "^2.7.6",
+ "npm-run-all": "^4.1.5",
+ "playwright-persona": "^0.2.6",
+ "prettier": "^3.5.3",
+ "prettier-plugin-sql": "^0.19.0",
+ "prettier-plugin-tailwindcss": "^0.6.11",
+ "react-router-devtools": "^5.0.5",
+ "remix-flat-routes": "^0.8.5",
+ "tsx": "^4.19.4",
+ "tw-animate-css": "^1.2.9",
+ "typescript": "^5.8.3",
+ "vite": "^6.3.5",
+ "vite-plugin-icons-spritesheet": "^3.0.1",
+ "vitest": "^3.1.3"
+ },
+ "engines": {
+ "node": "22.14.0"
+ },
+ "prisma": {
+ "seed": "tsx prisma/seed.ts"
+ },
+ "epic-stack": {
+ "head": "4e6532d08219cef41299615ad7556b205aa0b77d",
+ "date": "2025-07-02T03:11:12Z"
+ }
+}
diff --git a/exercises/02.test-setup/05.problem.test-data/playwright.config.ts b/exercises/02.authentication/05.solution.protected-logic/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/playwright.config.ts
rename to exercises/02.authentication/05.solution.protected-logic/playwright.config.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/prisma/migrations/20250221233640_init/migration.sql b/exercises/02.authentication/05.solution.protected-logic/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/02.authentication/05.solution.protected-logic/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/05.problem.test-data/prisma/migrations/migration_lock.toml b/exercises/02.authentication/05.solution.protected-logic/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/prisma/migrations/migration_lock.toml
rename to exercises/02.authentication/05.solution.protected-logic/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/05.problem.test-data/prisma/schema.prisma b/exercises/02.authentication/05.solution.protected-logic/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/prisma/schema.prisma
rename to exercises/02.authentication/05.solution.protected-logic/prisma/schema.prisma
diff --git a/exercises/02.test-setup/03.solution.authentication/prisma/seed.ts b/exercises/02.authentication/05.solution.protected-logic/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/prisma/seed.ts
rename to exercises/02.authentication/05.solution.protected-logic/prisma/seed.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/prisma/sql/searchUsers.sql b/exercises/02.authentication/05.solution.protected-logic/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/prisma/sql/searchUsers.sql
rename to exercises/02.authentication/05.solution.protected-logic/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/05.problem.test-data/public/favicon.ico b/exercises/02.authentication/05.solution.protected-logic/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/favicon.ico
rename to exercises/02.authentication/05.solution.protected-logic/public/favicon.ico
diff --git a/exercises/02.test-setup/05.problem.test-data/public/favicons/README.md b/exercises/02.authentication/05.solution.protected-logic/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/favicons/README.md
rename to exercises/02.authentication/05.solution.protected-logic/public/favicons/README.md
diff --git a/exercises/02.test-setup/05.problem.test-data/public/favicons/android-chrome-192x192.png b/exercises/02.authentication/05.solution.protected-logic/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/favicons/android-chrome-192x192.png
rename to exercises/02.authentication/05.solution.protected-logic/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/05.problem.test-data/public/favicons/android-chrome-512x512.png b/exercises/02.authentication/05.solution.protected-logic/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/favicons/android-chrome-512x512.png
rename to exercises/02.authentication/05.solution.protected-logic/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/05.problem.test-data/public/img/user.png b/exercises/02.authentication/05.solution.protected-logic/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/img/user.png
rename to exercises/02.authentication/05.solution.protected-logic/public/img/user.png
diff --git a/exercises/02.test-setup/05.problem.test-data/public/site.webmanifest b/exercises/02.authentication/05.solution.protected-logic/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/public/site.webmanifest
rename to exercises/02.authentication/05.solution.protected-logic/public/site.webmanifest
diff --git a/exercises/02.test-setup/05.problem.test-data/react-router.config.ts b/exercises/02.authentication/05.solution.protected-logic/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/react-router.config.ts
rename to exercises/02.authentication/05.solution.protected-logic/react-router.config.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/server/dev-server.js b/exercises/02.authentication/05.solution.protected-logic/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/server/dev-server.js
rename to exercises/02.authentication/05.solution.protected-logic/server/dev-server.js
diff --git a/exercises/02.test-setup/05.problem.test-data/server/index.ts b/exercises/02.authentication/05.solution.protected-logic/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/server/index.ts
rename to exercises/02.authentication/05.solution.protected-logic/server/index.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/server/utils/monitoring.ts b/exercises/02.authentication/05.solution.protected-logic/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/server/utils/monitoring.ts
rename to exercises/02.authentication/05.solution.protected-logic/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/db-utils.ts b/exercises/02.authentication/05.solution.protected-logic/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/db-utils.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/db-utils.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/e2e/notes-create.test.ts b/exercises/02.authentication/05.solution.protected-logic/tests/e2e/notes-create.test.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/e2e/notes-create.test.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/e2e/notes-create.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/setup/custom-matchers.ts b/exercises/02.authentication/05.solution.protected-logic/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/setup/custom-matchers.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/setup/db-setup.ts b/exercises/02.authentication/05.solution.protected-logic/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/setup/db-setup.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/setup/global-setup.ts b/exercises/02.authentication/05.solution.protected-logic/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/setup/global-setup.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/setup/setup-test-env.ts b/exercises/02.authentication/05.solution.protected-logic/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/setup/setup-test-env.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/03.solution.authentication/tests/test-extend.ts b/exercises/02.authentication/05.solution.protected-logic/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/tests/test-extend.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/test-extend.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/utils.ts b/exercises/02.authentication/05.solution.protected-logic/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/utils.ts
rename to exercises/02.authentication/05.solution.protected-logic/tests/utils.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tsconfig.json b/exercises/02.authentication/05.solution.protected-logic/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tsconfig.json
rename to exercises/02.authentication/05.solution.protected-logic/tsconfig.json
diff --git a/exercises/02.test-setup/05.problem.test-data/types/deps.d.ts b/exercises/02.authentication/05.solution.protected-logic/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/types/deps.d.ts
rename to exercises/02.authentication/05.solution.protected-logic/types/deps.d.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/types/env.env.d.ts b/exercises/02.authentication/05.solution.protected-logic/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/types/env.env.d.ts
rename to exercises/02.authentication/05.solution.protected-logic/types/env.env.d.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/types/icon-name.d.ts b/exercises/02.authentication/05.solution.protected-logic/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/types/icon-name.d.ts
rename to exercises/02.authentication/05.solution.protected-logic/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/types/reset.d.ts b/exercises/02.authentication/05.solution.protected-logic/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/types/reset.d.ts
rename to exercises/02.authentication/05.solution.protected-logic/types/reset.d.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/vite.config.ts b/exercises/02.authentication/05.solution.protected-logic/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/vite.config.ts
rename to exercises/02.authentication/05.solution.protected-logic/vite.config.ts
diff --git a/exercises/02.authentication/FINISHED.mdx b/exercises/02.authentication/FINISHED.mdx
new file mode 100644
index 0000000..66a783b
--- /dev/null
+++ b/exercises/02.authentication/FINISHED.mdx
@@ -0,0 +1 @@
+# Authentication
\ No newline at end of file
diff --git a/exercises/02.authentication/README.mdx b/exercises/02.authentication/README.mdx
new file mode 100644
index 0000000..f46cdf9
--- /dev/null
+++ b/exercises/02.authentication/README.mdx
@@ -0,0 +1,4 @@
+# Authentication
+
+- Show how to test different authentication options your application might have.
+- Show how to test logic that is _behind_ authentication (i.e. requires an authenticated user).
diff --git a/exercises/02.test-setup/02.problem.mock-databases/README.mdx b/exercises/02.test-setup/02.problem.mock-databases/README.mdx
deleted file mode 100644
index 33411d5..0000000
--- a/exercises/02.test-setup/02.problem.mock-databases/README.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
-# Mock databases
-
-Problem: Your app under test **must not** communicate with the actual database.
-
-Mocking database connections is database-specific. There are serveral kinds of databases you might be using:
-
-- **File-based** (SQLite). Just point it to a local file;
-- **Server-based** (Postgres). You can run that DB instance locally in a Docker image and point your DB client to that locally running DB instance.
-- **In-memory databases** (Redis). Run database locally (that's usually easier and doesn't require Docker), connect to the locally running instance.
-
-> Some database clients, like Supabase, might also expose an additional layer between your application and the database. You might decide to tap into that, too.
diff --git a/exercises/02.test-setup/02.problem.mock-databases/package.json b/exercises/02.test-setup/02.problem.mock-databases/package.json
deleted file mode 100644
index bf797b9..0000000
--- a/exercises/02.test-setup/02.problem.mock-databases/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "name": "exercises_02.test-setup_02.problem.mock-databases"
-}
diff --git a/exercises/02.test-setup/02.solution.mock-databases/README.mdx b/exercises/02.test-setup/02.solution.mock-databases/README.mdx
deleted file mode 100644
index e3f649a..0000000
--- a/exercises/02.test-setup/02.solution.mock-databases/README.mdx
+++ /dev/null
@@ -1,10 +0,0 @@
-# Mock databases
-
-Good job! 👏
-
-Take a quick rest and let's continue.
-
-## Related materials
-
-- [PostgreSQL test setup with Prisma](https://www.prisma.io/docs/orm/prisma-client/testing/integration-testing)
-- [Redus test setup (Node.js)](https://redis.io/docs/latest/develop/clients/nodejs/)
diff --git a/exercises/02.test-setup/02.solution.mock-databases/package.json b/exercises/02.test-setup/02.solution.mock-databases/package.json
deleted file mode 100644
index 334bcf0..0000000
--- a/exercises/02.test-setup/02.solution.mock-databases/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "name": "exercises_02.test-setup_02.solution.mock-databases"
-}
diff --git a/exercises/02.test-setup/FINISHED.mdx b/exercises/02.test-setup/FINISHED.mdx
deleted file mode 100644
index f593c92..0000000
--- a/exercises/02.test-setup/FINISHED.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-# Test setup
-
-Congratulations, you've completed this exercise block! 🥳 Let's have a short rest and continue.
-
-Meanwhile, I would be grateful if you _filled out the feedback form_ on your right. Your feedback helps me polish the exercises and improve the workshop before recording it. Thank you!
diff --git a/exercises/02.test-setup/README.mdx b/exercises/02.test-setup/README.mdx
deleted file mode 100644
index 5263799..0000000
--- a/exercises/02.test-setup/README.mdx
+++ /dev/null
@@ -1 +0,0 @@
-# Test setup
diff --git a/exercises/03.databases/01.solution.file-based/README.mdx b/exercises/03.databases/01.solution.file-based/README.mdx
new file mode 100644
index 0000000..3752382
--- /dev/null
+++ b/exercises/03.databases/01.solution.file-based/README.mdx
@@ -0,0 +1,4 @@
+# File-based
+
+- SQLite.
+- Configuring environment to use a different `DATABASE_URL`.
diff --git a/exercises/03.databases/02.solution.in-memory/README.mdx b/exercises/03.databases/02.solution.in-memory/README.mdx
new file mode 100644
index 0000000..4150ebf
--- /dev/null
+++ b/exercises/03.databases/02.solution.in-memory/README.mdx
@@ -0,0 +1,4 @@
+# In-memory
+
+- Redis.
+- In-memory, test database instances.
diff --git a/exercises/03.databases/03.solution.dockerized/README.mdx b/exercises/03.databases/03.solution.dockerized/README.mdx
new file mode 100644
index 0000000..dec4ac5
--- /dev/null
+++ b/exercises/03.databases/03.solution.dockerized/README.mdx
@@ -0,0 +1,4 @@
+# Dockerized
+
+- PostgreSQL.
+- TestContainers (?).
diff --git a/exercises/02.test-setup/05.solution.test-data/.env b/exercises/03.databases/04.problem.test-data/.env
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.env
rename to exercises/03.databases/04.problem.test-data/.env
diff --git a/exercises/02.test-setup/05.solution.test-data/.env.example b/exercises/03.databases/04.problem.test-data/.env.example
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.env.example
rename to exercises/03.databases/04.problem.test-data/.env.example
diff --git a/exercises/02.test-setup/03.problem.authentication/.github/PULL_REQUEST_TEMPLATE.md b/exercises/03.databases/04.problem.test-data/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/03.databases/04.problem.test-data/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/02.test-setup/03.problem.authentication/.github/workflows/deploy.yml b/exercises/03.databases/04.problem.test-data/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/02.test-setup/03.problem.authentication/.github/workflows/deploy.yml
rename to exercises/03.databases/04.problem.test-data/.github/workflows/deploy.yml
diff --git a/exercises/02.test-setup/05.solution.test-data/.gitignore b/exercises/03.databases/04.problem.test-data/.gitignore
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.gitignore
rename to exercises/03.databases/04.problem.test-data/.gitignore
diff --git a/exercises/02.test-setup/05.solution.test-data/.npmrc b/exercises/03.databases/04.problem.test-data/.npmrc
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.npmrc
rename to exercises/03.databases/04.problem.test-data/.npmrc
diff --git a/exercises/02.test-setup/05.solution.test-data/.prettierignore b/exercises/03.databases/04.problem.test-data/.prettierignore
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.prettierignore
rename to exercises/03.databases/04.problem.test-data/.prettierignore
diff --git a/exercises/02.test-setup/05.solution.test-data/.vscode/extensions.json b/exercises/03.databases/04.problem.test-data/.vscode/extensions.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.vscode/extensions.json
rename to exercises/03.databases/04.problem.test-data/.vscode/extensions.json
diff --git a/exercises/02.test-setup/05.solution.test-data/.vscode/remix.code-snippets b/exercises/03.databases/04.problem.test-data/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.vscode/remix.code-snippets
rename to exercises/03.databases/04.problem.test-data/.vscode/remix.code-snippets
diff --git a/exercises/02.test-setup/05.solution.test-data/.vscode/settings.json b/exercises/03.databases/04.problem.test-data/.vscode/settings.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/.vscode/settings.json
rename to exercises/03.databases/04.problem.test-data/.vscode/settings.json
diff --git a/exercises/02.test-setup/05.problem.test-data/README.mdx b/exercises/03.databases/04.problem.test-data/README.mdx
similarity index 96%
rename from exercises/02.test-setup/05.problem.test-data/README.mdx
rename to exercises/03.databases/04.problem.test-data/README.mdx
index 1d73031..3766109 100644
--- a/exercises/02.test-setup/05.problem.test-data/README.mdx
+++ b/exercises/03.databases/04.problem.test-data/README.mdx
@@ -1,5 +1,7 @@
# Test data
+- How to efficiently create and tear down test data.
+
## Your task
👨💼 In this one, your goal is to test that your app displays the list of user's notes. For that, the authenticated user must have some notes to display! The `user` we are creating via the `authenticate` function right now has no notes and you have to change that fact for this test case to pass.
diff --git a/exercises/02.test-setup/05.solution.test-data/app/assets/favicons/apple-touch-icon.png b/exercises/03.databases/04.problem.test-data/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/assets/favicons/apple-touch-icon.png
rename to exercises/03.databases/04.problem.test-data/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/02.test-setup/05.solution.test-data/app/assets/favicons/favicon.svg b/exercises/03.databases/04.problem.test-data/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/assets/favicons/favicon.svg
rename to exercises/03.databases/04.problem.test-data/app/assets/favicons/favicon.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/error-boundary.tsx b/exercises/03.databases/04.problem.test-data/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/error-boundary.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/error-boundary.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/floating-toolbar.tsx b/exercises/03.databases/04.problem.test-data/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/floating-toolbar.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/floating-toolbar.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/forms.tsx b/exercises/03.databases/04.problem.test-data/app/components/forms.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/forms.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/forms.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/progress-bar.tsx b/exercises/03.databases/04.problem.test-data/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/progress-bar.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/progress-bar.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/search-bar.tsx b/exercises/03.databases/04.problem.test-data/app/components/search-bar.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/search-bar.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/search-bar.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/spacer.tsx b/exercises/03.databases/04.problem.test-data/app/components/spacer.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/spacer.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/spacer.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/toaster.tsx b/exercises/03.databases/04.problem.test-data/app/components/toaster.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/toaster.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/toaster.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/README.md b/exercises/03.databases/04.problem.test-data/app/components/ui/README.md
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/README.md
rename to exercises/03.databases/04.problem.test-data/app/components/ui/README.md
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/button.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/button.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/button.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/button.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/checkbox.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/checkbox.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/checkbox.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/dropdown-menu.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/dropdown-menu.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/icon.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/icon.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/icon.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/input-otp.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/input-otp.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/input-otp.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/input.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/input.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/input.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/input.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/label.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/label.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/label.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/label.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/sonner.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/sonner.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/sonner.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/status-button.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/status-button.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/status-button.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/textarea.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/textarea.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/textarea.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/ui/tooltip.tsx b/exercises/03.databases/04.problem.test-data/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/ui/tooltip.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/ui/tooltip.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/components/user-dropdown.tsx b/exercises/03.databases/04.problem.test-data/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/components/user-dropdown.tsx
rename to exercises/03.databases/04.problem.test-data/app/components/user-dropdown.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/entry.client.tsx b/exercises/03.databases/04.problem.test-data/app/entry.client.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/entry.client.tsx
rename to exercises/03.databases/04.problem.test-data/app/entry.client.tsx
diff --git a/exercises/03.guides/01.solution.recording-interactions/app/entry.server.tsx b/exercises/03.databases/04.problem.test-data/app/entry.server.tsx
similarity index 100%
rename from exercises/03.guides/01.solution.recording-interactions/app/entry.server.tsx
rename to exercises/03.databases/04.problem.test-data/app/entry.server.tsx
diff --git a/exercises/03.guides/01.solution.recording-interactions/app/root.tsx b/exercises/03.databases/04.problem.test-data/app/root.tsx
similarity index 100%
rename from exercises/03.guides/01.solution.recording-interactions/app/root.tsx
rename to exercises/03.databases/04.problem.test-data/app/root.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes.ts b/exercises/03.databases/04.problem.test-data/app/routes.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes.ts
rename to exercises/03.databases/04.problem.test-data/app/routes.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/$.tsx b/exercises/03.databases/04.problem.test-data/app/routes/$.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/$.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/$.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/auth.$provider.callback.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/auth_.$provider.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/auth_.$provider.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/forgot-password.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/forgot-password.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/login.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/login.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/login.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/login.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/login.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/login.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/logout.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/logout.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/logout.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/reset-password.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/reset-password.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/reset-password.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/reset-password.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/signup.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/signup.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/signup.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/verify.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/verify.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/verify.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/verify.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/verify.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/verify.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/authentication.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/registration.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/about.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/about.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/about.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/index.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/index.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/index.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/docker.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/docker.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/eslint.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/eslint.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/faker.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/faker.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/fly.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/fly.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/github.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/github.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/logos.ts b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/logos.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/msw.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/msw.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/playwright.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/playwright.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/prettier.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/prettier.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/prisma.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/prisma.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/radix.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/radix.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/react-email.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/react-email.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/remix.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/remix.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/resend.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/resend.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/sentry.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/sentry.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/sqlite.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/stars.jpg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/stars.jpg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/tailwind.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/testing-library.png b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/testing-library.png
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/typescript.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/typescript.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/vitest.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/vitest.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/zod.svg b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/logos/zod.svg
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/privacy.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/privacy.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/support.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/support.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/support.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/tos.tsx b/exercises/03.databases/04.problem.test-data/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_marketing+/tos.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/_marketing+/tos.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_seo+/robots[.]txt.ts b/exercises/03.databases/04.problem.test-data/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_seo+/robots[.]txt.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/_seo+/sitemap[.]xml.ts b/exercises/03.databases/04.problem.test-data/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache.tsx b/exercises/03.databases/04.problem.test-data/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/admin+/cache.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.server.ts b/exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.tsx b/exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/me.tsx b/exercises/03.databases/04.problem.test-data/app/routes/me.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/me.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/me.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/resources+/download-user-data.tsx b/exercises/03.databases/04.problem.test-data/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/resources+/download-user-data.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/resources+/healthcheck.tsx b/exercises/03.databases/04.problem.test-data/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/resources+/healthcheck.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/resources+/images.tsx b/exercises/03.databases/04.problem.test-data/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/resources+/images.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/resources+/images.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/resources+/theme-switch.tsx b/exercises/03.databases/04.problem.test-data/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/resources+/theme-switch.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.change-email.server.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.change-email.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.change-email.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.connections.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.connections.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/03.guides/01.solution.recording-interactions/app/routes/settings+/profile.index.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/03.guides/01.solution.recording-interactions/app/routes/settings+/profile.index.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.index.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.passkeys.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.passkeys.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.password.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.password.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.password.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.password_.create.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.password_.create.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.photo.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.photo.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.index.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username.test.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/app/routes/users+/$username.test.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username.test.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/03.guides/01.solution.recording-interactions/app/routes/users+/$username_+/__note-editor.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/03.guides/01.solution.recording-interactions/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.index.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.new.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/app/routes/users+/$username_+/notes.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/index.tsx b/exercises/03.databases/04.problem.test-data/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/index.tsx
rename to exercises/03.databases/04.problem.test-data/app/routes/users+/index.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/styles/tailwind.css b/exercises/03.databases/04.problem.test-data/app/styles/tailwind.css
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/styles/tailwind.css
rename to exercises/03.databases/04.problem.test-data/app/styles/tailwind.css
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/auth.server.test.ts b/exercises/03.databases/04.problem.test-data/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/auth.server.test.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/auth.server.test.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/auth.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/auth.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/auth.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/auth.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/cache.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/cache.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/cache.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/cache.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/client-hints.tsx b/exercises/03.databases/04.problem.test-data/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/client-hints.tsx
rename to exercises/03.databases/04.problem.test-data/app/utils/client-hints.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/connections.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/connections.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/connections.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/connections.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/connections.tsx b/exercises/03.databases/04.problem.test-data/app/utils/connections.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/connections.tsx
rename to exercises/03.databases/04.problem.test-data/app/utils/connections.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/db.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/db.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/db.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/db.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/email.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/email.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/email.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/email.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/env.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/env.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/env.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/env.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/headers.server.test.ts b/exercises/03.databases/04.problem.test-data/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/headers.server.test.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/headers.server.test.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/headers.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/headers.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/headers.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/headers.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/honeypot.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/honeypot.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/honeypot.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/litefs.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/litefs.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/litefs.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/misc.error-message.test.ts b/exercises/03.databases/04.problem.test-data/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/misc.error-message.test.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/misc.error-message.test.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/misc.tsx b/exercises/03.databases/04.problem.test-data/app/utils/misc.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/misc.tsx
rename to exercises/03.databases/04.problem.test-data/app/utils/misc.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/misc.use-double-check.test.tsx b/exercises/03.databases/04.problem.test-data/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/misc.use-double-check.test.tsx
rename to exercises/03.databases/04.problem.test-data/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/monitoring.client.tsx b/exercises/03.databases/04.problem.test-data/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/monitoring.client.tsx
rename to exercises/03.databases/04.problem.test-data/app/utils/monitoring.client.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/nonce-provider.ts b/exercises/03.databases/04.problem.test-data/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/nonce-provider.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/nonce-provider.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/permissions.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/permissions.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/permissions.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/providers/constants.ts b/exercises/03.databases/04.problem.test-data/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/providers/constants.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/providers/constants.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/providers/github.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/providers/github.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/providers/github.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/providers/provider.ts b/exercises/03.databases/04.problem.test-data/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/providers/provider.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/providers/provider.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/redirect-cookie.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/redirect-cookie.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/redirect-cookie.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/request-info.ts b/exercises/03.databases/04.problem.test-data/app/utils/request-info.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/request-info.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/request-info.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/session.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/session.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/session.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/session.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/storage.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/storage.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/storage.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/storage.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/theme.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/theme.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/theme.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/theme.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/timing.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/timing.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/timing.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/timing.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/toast.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/toast.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/toast.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/toast.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/totp.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/totp.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/totp.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/totp.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/user-validation.ts b/exercises/03.databases/04.problem.test-data/app/utils/user-validation.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/user-validation.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/user-validation.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/user.ts b/exercises/03.databases/04.problem.test-data/app/utils/user.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/user.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/user.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/app/utils/verification.server.ts b/exercises/03.databases/04.problem.test-data/app/utils/verification.server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/utils/verification.server.ts
rename to exercises/03.databases/04.problem.test-data/app/utils/verification.server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/components.json b/exercises/03.databases/04.problem.test-data/components.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/components.json
rename to exercises/03.databases/04.problem.test-data/components.json
diff --git a/exercises/02.test-setup/05.solution.test-data/eslint.config.js b/exercises/03.databases/04.problem.test-data/eslint.config.js
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/eslint.config.js
rename to exercises/03.databases/04.problem.test-data/eslint.config.js
diff --git a/exercises/02.test-setup/05.solution.test-data/fly.toml b/exercises/03.databases/04.problem.test-data/fly.toml
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/fly.toml
rename to exercises/03.databases/04.problem.test-data/fly.toml
diff --git a/exercises/02.test-setup/05.solution.test-data/index.js b/exercises/03.databases/04.problem.test-data/index.js
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/index.js
rename to exercises/03.databases/04.problem.test-data/index.js
diff --git a/exercises/02.test-setup/05.solution.test-data/other/Dockerfile b/exercises/03.databases/04.problem.test-data/other/Dockerfile
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/Dockerfile
rename to exercises/03.databases/04.problem.test-data/other/Dockerfile
diff --git a/exercises/02.test-setup/05.solution.test-data/other/Dockerfile.dockerignore b/exercises/03.databases/04.problem.test-data/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/Dockerfile.dockerignore
rename to exercises/03.databases/04.problem.test-data/other/Dockerfile.dockerignore
diff --git a/exercises/02.test-setup/05.solution.test-data/other/README.md b/exercises/03.databases/04.problem.test-data/other/README.md
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/README.md
rename to exercises/03.databases/04.problem.test-data/other/README.md
diff --git a/exercises/02.test-setup/05.solution.test-data/other/build-server.ts b/exercises/03.databases/04.problem.test-data/other/build-server.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/build-server.ts
rename to exercises/03.databases/04.problem.test-data/other/build-server.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/other/litefs.yml b/exercises/03.databases/04.problem.test-data/other/litefs.yml
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/litefs.yml
rename to exercises/03.databases/04.problem.test-data/other/litefs.yml
diff --git a/exercises/02.test-setup/05.solution.test-data/other/sly/sly.json b/exercises/03.databases/04.problem.test-data/other/sly/sly.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/sly/sly.json
rename to exercises/03.databases/04.problem.test-data/other/sly/sly.json
diff --git a/exercises/02.test-setup/05.solution.test-data/other/sly/transform-icon.ts b/exercises/03.databases/04.problem.test-data/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/sly/transform-icon.ts
rename to exercises/03.databases/04.problem.test-data/other/sly/transform-icon.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/README.md b/exercises/03.databases/04.problem.test-data/other/svg-icons/README.md
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/README.md
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/README.md
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/arrow-left.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/arrow-left.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/arrow-left.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/arrow-right.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/arrow-right.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/arrow-right.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/avatar.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/avatar.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/avatar.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/camera.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/camera.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/camera.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/check.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/check.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/check.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/check.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/clock.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/clock.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/clock.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/cross-1.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/cross-1.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/cross-1.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/dots-horizontal.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/dots-horizontal.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/download.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/download.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/download.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/download.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/envelope-closed.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/envelope-closed.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/envelope-closed.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/exit.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/exit.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/exit.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/file-text.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/file-text.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/file-text.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/github-logo.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/github-logo.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/github-logo.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/laptop.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/laptop.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/laptop.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/link-2.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/link-2.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/link-2.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/lock-closed.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/lock-closed.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/lock-closed.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/lock-open-1.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/lock-open-1.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/lock-open-1.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/magnifying-glass.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/magnifying-glass.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/moon.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/moon.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/moon.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/passkey.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/passkey.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/passkey.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/pencil-1.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/pencil-1.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/pencil-1.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/pencil-2.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/pencil-2.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/pencil-2.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/plus.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/plus.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/plus.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/question-mark-circled.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/question-mark-circled.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/reset.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/reset.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/reset.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/sun.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/sun.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/sun.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/trash.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/trash.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/trash.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/other/svg-icons/update.svg b/exercises/03.databases/04.problem.test-data/other/svg-icons/update.svg
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/other/svg-icons/update.svg
rename to exercises/03.databases/04.problem.test-data/other/svg-icons/update.svg
diff --git a/exercises/02.test-setup/05.solution.test-data/package-lock.json b/exercises/03.databases/04.problem.test-data/package-lock.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/package-lock.json
rename to exercises/03.databases/04.problem.test-data/package-lock.json
diff --git a/exercises/02.test-setup/05.problem.test-data/package.json b/exercises/03.databases/04.problem.test-data/package.json
similarity index 98%
rename from exercises/02.test-setup/05.problem.test-data/package.json
rename to exercises/03.databases/04.problem.test-data/package.json
index b441ff8..396a9c2 100644
--- a/exercises/02.test-setup/05.problem.test-data/package.json
+++ b/exercises/03.databases/04.problem.test-data/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_02.test-setup_05.problem.test-data",
+ "name": "exercises_03.databases_04.problem.test-data",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/02.test-setup/05.solution.test-data/playwright.config.ts b/exercises/03.databases/04.problem.test-data/playwright.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/playwright.config.ts
rename to exercises/03.databases/04.problem.test-data/playwright.config.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/prisma/migrations/20250221233640_init/migration.sql b/exercises/03.databases/04.problem.test-data/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/03.databases/04.problem.test-data/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/02.test-setup/05.solution.test-data/prisma/migrations/migration_lock.toml b/exercises/03.databases/04.problem.test-data/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/prisma/migrations/migration_lock.toml
rename to exercises/03.databases/04.problem.test-data/prisma/migrations/migration_lock.toml
diff --git a/exercises/02.test-setup/05.solution.test-data/prisma/schema.prisma b/exercises/03.databases/04.problem.test-data/prisma/schema.prisma
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/prisma/schema.prisma
rename to exercises/03.databases/04.problem.test-data/prisma/schema.prisma
diff --git a/exercises/02.test-setup/04.problem.api-mocking/prisma/seed.ts b/exercises/03.databases/04.problem.test-data/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/prisma/seed.ts
rename to exercises/03.databases/04.problem.test-data/prisma/seed.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/prisma/sql/searchUsers.sql b/exercises/03.databases/04.problem.test-data/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/prisma/sql/searchUsers.sql
rename to exercises/03.databases/04.problem.test-data/prisma/sql/searchUsers.sql
diff --git a/exercises/02.test-setup/05.solution.test-data/public/favicon.ico b/exercises/03.databases/04.problem.test-data/public/favicon.ico
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/favicon.ico
rename to exercises/03.databases/04.problem.test-data/public/favicon.ico
diff --git a/exercises/02.test-setup/05.solution.test-data/public/favicons/README.md b/exercises/03.databases/04.problem.test-data/public/favicons/README.md
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/favicons/README.md
rename to exercises/03.databases/04.problem.test-data/public/favicons/README.md
diff --git a/exercises/02.test-setup/05.solution.test-data/public/favicons/android-chrome-192x192.png b/exercises/03.databases/04.problem.test-data/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/favicons/android-chrome-192x192.png
rename to exercises/03.databases/04.problem.test-data/public/favicons/android-chrome-192x192.png
diff --git a/exercises/02.test-setup/05.solution.test-data/public/favicons/android-chrome-512x512.png b/exercises/03.databases/04.problem.test-data/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/favicons/android-chrome-512x512.png
rename to exercises/03.databases/04.problem.test-data/public/favicons/android-chrome-512x512.png
diff --git a/exercises/02.test-setup/05.solution.test-data/public/img/user.png b/exercises/03.databases/04.problem.test-data/public/img/user.png
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/img/user.png
rename to exercises/03.databases/04.problem.test-data/public/img/user.png
diff --git a/exercises/02.test-setup/05.solution.test-data/public/site.webmanifest b/exercises/03.databases/04.problem.test-data/public/site.webmanifest
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/public/site.webmanifest
rename to exercises/03.databases/04.problem.test-data/public/site.webmanifest
diff --git a/exercises/02.test-setup/05.solution.test-data/react-router.config.ts b/exercises/03.databases/04.problem.test-data/react-router.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/react-router.config.ts
rename to exercises/03.databases/04.problem.test-data/react-router.config.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/server/dev-server.js b/exercises/03.databases/04.problem.test-data/server/dev-server.js
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/server/dev-server.js
rename to exercises/03.databases/04.problem.test-data/server/dev-server.js
diff --git a/exercises/02.test-setup/05.solution.test-data/server/index.ts b/exercises/03.databases/04.problem.test-data/server/index.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/server/index.ts
rename to exercises/03.databases/04.problem.test-data/server/index.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/server/utils/monitoring.ts b/exercises/03.databases/04.problem.test-data/server/utils/monitoring.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/server/utils/monitoring.ts
rename to exercises/03.databases/04.problem.test-data/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/04.problem.api-mocking/tests/db-utils.ts b/exercises/03.databases/04.problem.test-data/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/04.problem.api-mocking/tests/db-utils.ts
rename to exercises/03.databases/04.problem.test-data/tests/db-utils.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/e2e/notes-list.test.ts b/exercises/03.databases/04.problem.test-data/tests/e2e/notes-list.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/e2e/notes-list.test.ts
rename to exercises/03.databases/04.problem.test-data/tests/e2e/notes-list.test.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/e2e/utils.ts b/exercises/03.databases/04.problem.test-data/tests/e2e/utils.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/e2e/utils.ts
rename to exercises/03.databases/04.problem.test-data/tests/e2e/utils.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/setup/custom-matchers.ts b/exercises/03.databases/04.problem.test-data/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/setup/custom-matchers.ts
rename to exercises/03.databases/04.problem.test-data/tests/setup/custom-matchers.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/setup/db-setup.ts b/exercises/03.databases/04.problem.test-data/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/setup/db-setup.ts
rename to exercises/03.databases/04.problem.test-data/tests/setup/db-setup.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/setup/global-setup.ts b/exercises/03.databases/04.problem.test-data/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/setup/global-setup.ts
rename to exercises/03.databases/04.problem.test-data/tests/setup/global-setup.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/setup/setup-test-env.ts b/exercises/03.databases/04.problem.test-data/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/setup/setup-test-env.ts
rename to exercises/03.databases/04.problem.test-data/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/05.problem.test-data/tests/test-extend.ts b/exercises/03.databases/04.problem.test-data/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/05.problem.test-data/tests/test-extend.ts
rename to exercises/03.databases/04.problem.test-data/tests/test-extend.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/utils.ts b/exercises/03.databases/04.problem.test-data/tests/utils.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/utils.ts
rename to exercises/03.databases/04.problem.test-data/tests/utils.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tsconfig.json b/exercises/03.databases/04.problem.test-data/tsconfig.json
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tsconfig.json
rename to exercises/03.databases/04.problem.test-data/tsconfig.json
diff --git a/exercises/02.test-setup/05.solution.test-data/types/deps.d.ts b/exercises/03.databases/04.problem.test-data/types/deps.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/types/deps.d.ts
rename to exercises/03.databases/04.problem.test-data/types/deps.d.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/types/env.env.d.ts b/exercises/03.databases/04.problem.test-data/types/env.env.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/types/env.env.d.ts
rename to exercises/03.databases/04.problem.test-data/types/env.env.d.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/types/icon-name.d.ts b/exercises/03.databases/04.problem.test-data/types/icon-name.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/types/icon-name.d.ts
rename to exercises/03.databases/04.problem.test-data/types/icon-name.d.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/types/reset.d.ts b/exercises/03.databases/04.problem.test-data/types/reset.d.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/types/reset.d.ts
rename to exercises/03.databases/04.problem.test-data/types/reset.d.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/vite.config.ts b/exercises/03.databases/04.problem.test-data/vite.config.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/vite.config.ts
rename to exercises/03.databases/04.problem.test-data/vite.config.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/.env b/exercises/03.databases/04.solution.test-data/.env
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.env
rename to exercises/03.databases/04.solution.test-data/.env
diff --git a/exercises/03.guides/01.problem.recording-interactions/.env.example b/exercises/03.databases/04.solution.test-data/.env.example
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.env.example
rename to exercises/03.databases/04.solution.test-data/.env.example
diff --git a/exercises/02.test-setup/03.solution.authentication/.github/PULL_REQUEST_TEMPLATE.md b/exercises/03.databases/04.solution.test-data/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.github/PULL_REQUEST_TEMPLATE.md
rename to exercises/03.databases/04.solution.test-data/.github/PULL_REQUEST_TEMPLATE.md
diff --git a/exercises/02.test-setup/03.solution.authentication/.github/workflows/deploy.yml b/exercises/03.databases/04.solution.test-data/.github/workflows/deploy.yml
similarity index 100%
rename from exercises/02.test-setup/03.solution.authentication/.github/workflows/deploy.yml
rename to exercises/03.databases/04.solution.test-data/.github/workflows/deploy.yml
diff --git a/exercises/03.guides/01.problem.recording-interactions/.gitignore b/exercises/03.databases/04.solution.test-data/.gitignore
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.gitignore
rename to exercises/03.databases/04.solution.test-data/.gitignore
diff --git a/exercises/03.guides/01.problem.recording-interactions/.npmrc b/exercises/03.databases/04.solution.test-data/.npmrc
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.npmrc
rename to exercises/03.databases/04.solution.test-data/.npmrc
diff --git a/exercises/03.guides/01.problem.recording-interactions/.prettierignore b/exercises/03.databases/04.solution.test-data/.prettierignore
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.prettierignore
rename to exercises/03.databases/04.solution.test-data/.prettierignore
diff --git a/exercises/04.debugging/02.problem.trace-viewer/.vscode/extensions.json b/exercises/03.databases/04.solution.test-data/.vscode/extensions.json
similarity index 75%
rename from exercises/04.debugging/02.problem.trace-viewer/.vscode/extensions.json
rename to exercises/03.databases/04.solution.test-data/.vscode/extensions.json
index f724eea..3c0a690 100644
--- a/exercises/04.debugging/02.problem.trace-viewer/.vscode/extensions.json
+++ b/exercises/03.databases/04.solution.test-data/.vscode/extensions.json
@@ -6,7 +6,6 @@
"prisma.prisma",
"qwtel.sqlite-viewer",
"yoavbls.pretty-ts-errors",
- "github.vscode-github-actions",
- "ms-playwright.playwright"
+ "github.vscode-github-actions"
]
}
diff --git a/exercises/03.guides/01.problem.recording-interactions/.vscode/remix.code-snippets b/exercises/03.databases/04.solution.test-data/.vscode/remix.code-snippets
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.vscode/remix.code-snippets
rename to exercises/03.databases/04.solution.test-data/.vscode/remix.code-snippets
diff --git a/exercises/03.guides/01.problem.recording-interactions/.vscode/settings.json b/exercises/03.databases/04.solution.test-data/.vscode/settings.json
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/.vscode/settings.json
rename to exercises/03.databases/04.solution.test-data/.vscode/settings.json
diff --git a/exercises/02.test-setup/05.solution.test-data/README.mdx b/exercises/03.databases/04.solution.test-data/README.mdx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/README.mdx
rename to exercises/03.databases/04.solution.test-data/README.mdx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/assets/favicons/apple-touch-icon.png b/exercises/03.databases/04.solution.test-data/app/assets/favicons/apple-touch-icon.png
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/assets/favicons/apple-touch-icon.png
rename to exercises/03.databases/04.solution.test-data/app/assets/favicons/apple-touch-icon.png
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/assets/favicons/favicon.svg b/exercises/03.databases/04.solution.test-data/app/assets/favicons/favicon.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/assets/favicons/favicon.svg
rename to exercises/03.databases/04.solution.test-data/app/assets/favicons/favicon.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/error-boundary.tsx b/exercises/03.databases/04.solution.test-data/app/components/error-boundary.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/error-boundary.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/error-boundary.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/floating-toolbar.tsx b/exercises/03.databases/04.solution.test-data/app/components/floating-toolbar.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/floating-toolbar.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/floating-toolbar.tsx
diff --git a/exercises/03.guides/01.solution.recording-interactions/app/components/forms.tsx b/exercises/03.databases/04.solution.test-data/app/components/forms.tsx
similarity index 100%
rename from exercises/03.guides/01.solution.recording-interactions/app/components/forms.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/forms.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/progress-bar.tsx b/exercises/03.databases/04.solution.test-data/app/components/progress-bar.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/progress-bar.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/progress-bar.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/search-bar.tsx b/exercises/03.databases/04.solution.test-data/app/components/search-bar.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/search-bar.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/search-bar.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/spacer.tsx b/exercises/03.databases/04.solution.test-data/app/components/spacer.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/spacer.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/spacer.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/toaster.tsx b/exercises/03.databases/04.solution.test-data/app/components/toaster.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/toaster.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/toaster.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/README.md b/exercises/03.databases/04.solution.test-data/app/components/ui/README.md
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/README.md
rename to exercises/03.databases/04.solution.test-data/app/components/ui/README.md
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/button.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/button.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/button.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/button.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/checkbox.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/checkbox.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/checkbox.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/checkbox.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/dropdown-menu.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/dropdown-menu.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/dropdown-menu.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/icon.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/icon.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/icon.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/icon.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/input-otp.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/input-otp.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/input-otp.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/input-otp.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/input.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/input.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/input.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/input.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/label.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/label.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/label.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/label.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/sonner.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/sonner.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/sonner.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/sonner.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/status-button.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/status-button.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/status-button.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/status-button.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/textarea.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/textarea.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/textarea.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/textarea.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/ui/tooltip.tsx b/exercises/03.databases/04.solution.test-data/app/components/ui/tooltip.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/ui/tooltip.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/ui/tooltip.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/components/user-dropdown.tsx b/exercises/03.databases/04.solution.test-data/app/components/user-dropdown.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/components/user-dropdown.tsx
rename to exercises/03.databases/04.solution.test-data/app/components/user-dropdown.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/entry.client.tsx b/exercises/03.databases/04.solution.test-data/app/entry.client.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/entry.client.tsx
rename to exercises/03.databases/04.solution.test-data/app/entry.client.tsx
diff --git a/exercises/03.guides/02.problem.test-annotations/app/entry.server.tsx b/exercises/03.databases/04.solution.test-data/app/entry.server.tsx
similarity index 100%
rename from exercises/03.guides/02.problem.test-annotations/app/entry.server.tsx
rename to exercises/03.databases/04.solution.test-data/app/entry.server.tsx
diff --git a/exercises/03.guides/02.problem.test-annotations/app/root.tsx b/exercises/03.databases/04.solution.test-data/app/root.tsx
similarity index 100%
rename from exercises/03.guides/02.problem.test-annotations/app/root.tsx
rename to exercises/03.databases/04.solution.test-data/app/root.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes.ts b/exercises/03.databases/04.solution.test-data/app/routes.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes.ts
rename to exercises/03.databases/04.solution.test-data/app/routes.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/$.tsx b/exercises/03.databases/04.solution.test-data/app/routes/$.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/$.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/$.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth.$provider.callback.test.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/_auth+/auth.$provider.callback.test.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth.$provider.callback.test.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/auth.$provider.callback.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth.$provider.callback.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/auth.$provider.callback.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth.$provider.callback.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/auth_.$provider.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth_.$provider.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/auth_.$provider.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/auth_.$provider.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/forgot-password.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/forgot-password.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/forgot-password.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/forgot-password.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/login.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/login.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/login.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/login.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/login.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/login.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/login.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/login.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/logout.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/logout.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/logout.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/logout.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding_.$provider.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding_.$provider.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding_.$provider.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding_.$provider.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding_.$provider.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/onboarding_.$provider.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/onboarding_.$provider.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/reset-password.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/reset-password.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/reset-password.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/reset-password.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/reset-password.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/reset-password.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/reset-password.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/reset-password.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/signup.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/signup.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/signup.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/signup.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/verify.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/verify.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/verify.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/verify.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/verify.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/verify.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/verify.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/verify.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/authentication.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/authentication.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/authentication.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/authentication.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/registration.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/registration.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/registration.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/registration.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/utils.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/utils.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_auth+/webauthn+/utils.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_auth+/webauthn+/utils.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/about.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/about.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/about.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/about.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/index.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/index.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/index.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/index.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/docker.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/docker.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/docker.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/docker.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/eslint.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/eslint.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/eslint.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/eslint.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/faker.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/faker.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/faker.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/faker.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/fly.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/fly.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/fly.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/fly.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/github.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/github.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/github.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/github.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/logos.ts b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/logos.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/logos.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/logos.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/msw.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/msw.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/msw.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/msw.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/playwright.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/playwright.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/playwright.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/playwright.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/prettier.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/prettier.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/prettier.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/prettier.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/prisma.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/prisma.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/prisma.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/prisma.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/radix.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/radix.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/radix.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/radix.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/react-email.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/react-email.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/react-email.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/react-email.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/remix.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/remix.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/remix.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/remix.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/resend.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/resend.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/resend.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/resend.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/sentry.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/sentry.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/sentry.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/sentry.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/shadcn-ui.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/shadcn-ui.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/shadcn-ui.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/sqlite.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/sqlite.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/sqlite.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/sqlite.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/stars.jpg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/stars.jpg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/stars.jpg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/stars.jpg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/tailwind.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/tailwind.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/tailwind.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/tailwind.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/testing-library.png b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/testing-library.png
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/testing-library.png
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/testing-library.png
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/typescript.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/typescript.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/typescript.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/typescript.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/vitest.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/vitest.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/vitest.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/vitest.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/zod.svg b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/zod.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/logos/zod.svg
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/logos/zod.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/privacy.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/privacy.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/privacy.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/privacy.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/support.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/support.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/support.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/support.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/tos.tsx b/exercises/03.databases/04.solution.test-data/app/routes/_marketing+/tos.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_marketing+/tos.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/_marketing+/tos.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_seo+/robots[.]txt.ts b/exercises/03.databases/04.solution.test-data/app/routes/_seo+/robots[.]txt.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_seo+/robots[.]txt.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_seo+/robots[.]txt.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/_seo+/sitemap[.]xml.ts b/exercises/03.databases/04.solution.test-data/app/routes/_seo+/sitemap[.]xml.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/_seo+/sitemap[.]xml.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/_seo+/sitemap[.]xml.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache.tsx b/exercises/03.databases/04.solution.test-data/app/routes/admin+/cache.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/admin+/cache.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.lru.$cacheKey.ts b/exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.lru.$cacheKey.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.lru.$cacheKey.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.$cacheKey.ts b/exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.$cacheKey.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.$cacheKey.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.server.ts b/exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.server.ts
rename to exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.tsx b/exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/admin+/cache_.sqlite.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/admin+/cache_.sqlite.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/me.tsx b/exercises/03.databases/04.solution.test-data/app/routes/me.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/me.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/me.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/download-user-data.tsx b/exercises/03.databases/04.solution.test-data/app/routes/resources+/download-user-data.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/download-user-data.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/resources+/download-user-data.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/healthcheck.tsx b/exercises/03.databases/04.solution.test-data/app/routes/resources+/healthcheck.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/healthcheck.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/resources+/healthcheck.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/images.tsx b/exercises/03.databases/04.solution.test-data/app/routes/resources+/images.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/images.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/resources+/images.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/theme-switch.tsx b/exercises/03.databases/04.solution.test-data/app/routes/resources+/theme-switch.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/resources+/theme-switch.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/resources+/theme-switch.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.change-email.server.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.change-email.server.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.change-email.server.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.change-email.server.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.change-email.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.change-email.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.change-email.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.change-email.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.connections.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.connections.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.connections.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.connections.tsx
diff --git a/exercises/03.guides/02.problem.test-annotations/app/routes/settings+/profile.index.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.index.tsx
similarity index 100%
rename from exercises/03.guides/02.problem.test-annotations/app/routes/settings+/profile.index.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.index.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.passkeys.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.passkeys.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.passkeys.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.passkeys.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.password.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.password.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.password.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.password.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.password_.create.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.password_.create.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.password_.create.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.password_.create.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.photo.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.photo.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.photo.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.photo.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.disable.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.disable.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.disable.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.disable.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.index.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.index.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.index.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.index.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.verify.tsx b/exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.verify.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/settings+/profile.two-factor.verify.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/settings+/profile.two-factor.verify.tsx
diff --git a/exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username.test.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username.test.tsx
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/app/routes/users+/$username.test.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username.test.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/__note-editor.server.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/__note-editor.server.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/__note-editor.server.tsx
diff --git a/exercises/03.guides/02.problem.test-annotations/app/routes/users+/$username_+/__note-editor.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/__note-editor.tsx
similarity index 100%
rename from exercises/03.guides/02.problem.test-annotations/app/routes/users+/$username_+/__note-editor.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/__note-editor.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.$noteId.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.$noteId.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.$noteId.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.$noteId_.edit.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.$noteId_.edit.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.index.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.index.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.index.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.index.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.new.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.new.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/$username_+/notes.new.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.new.tsx
diff --git a/exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.tsx
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/app/routes/users+/$username_+/notes.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/$username_+/notes.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/routes/users+/index.tsx b/exercises/03.databases/04.solution.test-data/app/routes/users+/index.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/routes/users+/index.tsx
rename to exercises/03.databases/04.solution.test-data/app/routes/users+/index.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/styles/tailwind.css b/exercises/03.databases/04.solution.test-data/app/styles/tailwind.css
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/styles/tailwind.css
rename to exercises/03.databases/04.solution.test-data/app/styles/tailwind.css
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/auth.server.test.ts b/exercises/03.databases/04.solution.test-data/app/utils/auth.server.test.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/auth.server.test.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/auth.server.test.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/auth.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/auth.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/auth.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/auth.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/cache.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/cache.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/cache.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/cache.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/client-hints.tsx b/exercises/03.databases/04.solution.test-data/app/utils/client-hints.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/client-hints.tsx
rename to exercises/03.databases/04.solution.test-data/app/utils/client-hints.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/connections.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/connections.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/connections.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/connections.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/connections.tsx b/exercises/03.databases/04.solution.test-data/app/utils/connections.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/connections.tsx
rename to exercises/03.databases/04.solution.test-data/app/utils/connections.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/db.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/db.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/db.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/db.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/email.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/email.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/email.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/email.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/env.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/env.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/env.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/env.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/headers.server.test.ts b/exercises/03.databases/04.solution.test-data/app/utils/headers.server.test.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/headers.server.test.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/headers.server.test.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/headers.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/headers.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/headers.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/headers.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/honeypot.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/honeypot.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/honeypot.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/honeypot.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/litefs.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/litefs.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/litefs.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/litefs.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/misc.error-message.test.ts b/exercises/03.databases/04.solution.test-data/app/utils/misc.error-message.test.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/misc.error-message.test.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/misc.error-message.test.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/misc.tsx b/exercises/03.databases/04.solution.test-data/app/utils/misc.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/misc.tsx
rename to exercises/03.databases/04.solution.test-data/app/utils/misc.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/misc.use-double-check.test.tsx b/exercises/03.databases/04.solution.test-data/app/utils/misc.use-double-check.test.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/misc.use-double-check.test.tsx
rename to exercises/03.databases/04.solution.test-data/app/utils/misc.use-double-check.test.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/monitoring.client.tsx b/exercises/03.databases/04.solution.test-data/app/utils/monitoring.client.tsx
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/monitoring.client.tsx
rename to exercises/03.databases/04.solution.test-data/app/utils/monitoring.client.tsx
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/nonce-provider.ts b/exercises/03.databases/04.solution.test-data/app/utils/nonce-provider.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/nonce-provider.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/nonce-provider.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/permissions.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/permissions.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/permissions.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/permissions.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/providers/constants.ts b/exercises/03.databases/04.solution.test-data/app/utils/providers/constants.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/providers/constants.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/providers/constants.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/providers/github.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/providers/github.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/providers/github.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/providers/github.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/providers/provider.ts b/exercises/03.databases/04.solution.test-data/app/utils/providers/provider.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/providers/provider.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/providers/provider.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/redirect-cookie.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/redirect-cookie.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/redirect-cookie.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/redirect-cookie.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/request-info.ts b/exercises/03.databases/04.solution.test-data/app/utils/request-info.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/request-info.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/request-info.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/session.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/session.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/session.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/session.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/storage.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/storage.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/storage.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/storage.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/theme.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/theme.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/theme.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/theme.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/timing.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/timing.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/timing.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/timing.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/toast.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/toast.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/toast.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/toast.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/totp.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/totp.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/totp.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/totp.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/user-validation.ts b/exercises/03.databases/04.solution.test-data/app/utils/user-validation.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/user-validation.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/user-validation.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/user.ts b/exercises/03.databases/04.solution.test-data/app/utils/user.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/user.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/user.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/app/utils/verification.server.ts b/exercises/03.databases/04.solution.test-data/app/utils/verification.server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/app/utils/verification.server.ts
rename to exercises/03.databases/04.solution.test-data/app/utils/verification.server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/components.json b/exercises/03.databases/04.solution.test-data/components.json
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/components.json
rename to exercises/03.databases/04.solution.test-data/components.json
diff --git a/exercises/03.guides/01.problem.recording-interactions/eslint.config.js b/exercises/03.databases/04.solution.test-data/eslint.config.js
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/eslint.config.js
rename to exercises/03.databases/04.solution.test-data/eslint.config.js
diff --git a/exercises/03.guides/01.problem.recording-interactions/fly.toml b/exercises/03.databases/04.solution.test-data/fly.toml
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/fly.toml
rename to exercises/03.databases/04.solution.test-data/fly.toml
diff --git a/exercises/03.guides/01.problem.recording-interactions/index.js b/exercises/03.databases/04.solution.test-data/index.js
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/index.js
rename to exercises/03.databases/04.solution.test-data/index.js
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/Dockerfile b/exercises/03.databases/04.solution.test-data/other/Dockerfile
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/Dockerfile
rename to exercises/03.databases/04.solution.test-data/other/Dockerfile
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/Dockerfile.dockerignore b/exercises/03.databases/04.solution.test-data/other/Dockerfile.dockerignore
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/Dockerfile.dockerignore
rename to exercises/03.databases/04.solution.test-data/other/Dockerfile.dockerignore
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/README.md b/exercises/03.databases/04.solution.test-data/other/README.md
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/README.md
rename to exercises/03.databases/04.solution.test-data/other/README.md
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/build-server.ts b/exercises/03.databases/04.solution.test-data/other/build-server.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/build-server.ts
rename to exercises/03.databases/04.solution.test-data/other/build-server.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/litefs.yml b/exercises/03.databases/04.solution.test-data/other/litefs.yml
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/litefs.yml
rename to exercises/03.databases/04.solution.test-data/other/litefs.yml
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/sly/sly.json b/exercises/03.databases/04.solution.test-data/other/sly/sly.json
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/sly/sly.json
rename to exercises/03.databases/04.solution.test-data/other/sly/sly.json
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/sly/transform-icon.ts b/exercises/03.databases/04.solution.test-data/other/sly/transform-icon.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/sly/transform-icon.ts
rename to exercises/03.databases/04.solution.test-data/other/sly/transform-icon.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/README.md b/exercises/03.databases/04.solution.test-data/other/svg-icons/README.md
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/README.md
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/README.md
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/arrow-left.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/arrow-left.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/arrow-left.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/arrow-left.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/arrow-right.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/arrow-right.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/arrow-right.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/arrow-right.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/avatar.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/avatar.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/avatar.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/avatar.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/camera.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/camera.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/camera.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/camera.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/check.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/check.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/check.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/check.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/clock.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/clock.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/clock.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/clock.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/cross-1.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/cross-1.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/cross-1.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/cross-1.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/dots-horizontal.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/dots-horizontal.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/dots-horizontal.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/dots-horizontal.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/download.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/download.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/download.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/download.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/envelope-closed.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/envelope-closed.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/envelope-closed.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/envelope-closed.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/exit.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/exit.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/exit.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/exit.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/file-text.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/file-text.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/file-text.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/file-text.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/github-logo.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/github-logo.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/github-logo.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/github-logo.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/laptop.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/laptop.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/laptop.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/laptop.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/link-2.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/link-2.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/link-2.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/link-2.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/lock-closed.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/lock-closed.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/lock-closed.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/lock-closed.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/lock-open-1.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/lock-open-1.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/lock-open-1.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/lock-open-1.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/magnifying-glass.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/magnifying-glass.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/magnifying-glass.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/magnifying-glass.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/moon.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/moon.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/moon.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/moon.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/passkey.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/passkey.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/passkey.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/passkey.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/pencil-1.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/pencil-1.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/pencil-1.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/pencil-1.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/pencil-2.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/pencil-2.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/pencil-2.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/pencil-2.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/plus.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/plus.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/plus.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/plus.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/question-mark-circled.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/question-mark-circled.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/question-mark-circled.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/question-mark-circled.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/reset.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/reset.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/reset.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/reset.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/sun.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/sun.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/sun.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/sun.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/trash.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/trash.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/trash.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/trash.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/other/svg-icons/update.svg b/exercises/03.databases/04.solution.test-data/other/svg-icons/update.svg
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/other/svg-icons/update.svg
rename to exercises/03.databases/04.solution.test-data/other/svg-icons/update.svg
diff --git a/exercises/03.guides/01.problem.recording-interactions/package-lock.json b/exercises/03.databases/04.solution.test-data/package-lock.json
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/package-lock.json
rename to exercises/03.databases/04.solution.test-data/package-lock.json
diff --git a/exercises/03.guides/02.problem.test-annotations/package.json b/exercises/03.databases/04.solution.test-data/package.json
similarity index 98%
rename from exercises/03.guides/02.problem.test-annotations/package.json
rename to exercises/03.databases/04.solution.test-data/package.json
index 471ccd8..3d0123b 100644
--- a/exercises/03.guides/02.problem.test-annotations/package.json
+++ b/exercises/03.databases/04.solution.test-data/package.json
@@ -1,5 +1,5 @@
{
- "name": "exercises_03.guides_02.problem.test-annotations",
+ "name": "exercises_03.databases_04.solution.test-data",
"private": true,
"sideEffects": false,
"type": "module",
diff --git a/exercises/03.guides/01.problem.recording-interactions/playwright.config.ts b/exercises/03.databases/04.solution.test-data/playwright.config.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/playwright.config.ts
rename to exercises/03.databases/04.solution.test-data/playwright.config.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/prisma/migrations/20250221233640_init/migration.sql b/exercises/03.databases/04.solution.test-data/prisma/migrations/20250221233640_init/migration.sql
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/prisma/migrations/20250221233640_init/migration.sql
rename to exercises/03.databases/04.solution.test-data/prisma/migrations/20250221233640_init/migration.sql
diff --git a/exercises/03.guides/01.problem.recording-interactions/prisma/migrations/migration_lock.toml b/exercises/03.databases/04.solution.test-data/prisma/migrations/migration_lock.toml
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/prisma/migrations/migration_lock.toml
rename to exercises/03.databases/04.solution.test-data/prisma/migrations/migration_lock.toml
diff --git a/exercises/03.guides/01.problem.recording-interactions/prisma/schema.prisma b/exercises/03.databases/04.solution.test-data/prisma/schema.prisma
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/prisma/schema.prisma
rename to exercises/03.databases/04.solution.test-data/prisma/schema.prisma
diff --git a/exercises/02.test-setup/04.solution.api-mocking/prisma/seed.ts b/exercises/03.databases/04.solution.test-data/prisma/seed.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/prisma/seed.ts
rename to exercises/03.databases/04.solution.test-data/prisma/seed.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/prisma/sql/searchUsers.sql b/exercises/03.databases/04.solution.test-data/prisma/sql/searchUsers.sql
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/prisma/sql/searchUsers.sql
rename to exercises/03.databases/04.solution.test-data/prisma/sql/searchUsers.sql
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/favicon.ico b/exercises/03.databases/04.solution.test-data/public/favicon.ico
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/favicon.ico
rename to exercises/03.databases/04.solution.test-data/public/favicon.ico
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/favicons/README.md b/exercises/03.databases/04.solution.test-data/public/favicons/README.md
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/favicons/README.md
rename to exercises/03.databases/04.solution.test-data/public/favicons/README.md
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/favicons/android-chrome-192x192.png b/exercises/03.databases/04.solution.test-data/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/favicons/android-chrome-192x192.png
rename to exercises/03.databases/04.solution.test-data/public/favicons/android-chrome-192x192.png
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/favicons/android-chrome-512x512.png b/exercises/03.databases/04.solution.test-data/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/favicons/android-chrome-512x512.png
rename to exercises/03.databases/04.solution.test-data/public/favicons/android-chrome-512x512.png
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/img/user.png b/exercises/03.databases/04.solution.test-data/public/img/user.png
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/img/user.png
rename to exercises/03.databases/04.solution.test-data/public/img/user.png
diff --git a/exercises/03.guides/01.problem.recording-interactions/public/site.webmanifest b/exercises/03.databases/04.solution.test-data/public/site.webmanifest
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/public/site.webmanifest
rename to exercises/03.databases/04.solution.test-data/public/site.webmanifest
diff --git a/exercises/03.guides/01.problem.recording-interactions/react-router.config.ts b/exercises/03.databases/04.solution.test-data/react-router.config.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/react-router.config.ts
rename to exercises/03.databases/04.solution.test-data/react-router.config.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/server/dev-server.js b/exercises/03.databases/04.solution.test-data/server/dev-server.js
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/server/dev-server.js
rename to exercises/03.databases/04.solution.test-data/server/dev-server.js
diff --git a/exercises/03.guides/01.problem.recording-interactions/server/index.ts b/exercises/03.databases/04.solution.test-data/server/index.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/server/index.ts
rename to exercises/03.databases/04.solution.test-data/server/index.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/server/utils/monitoring.ts b/exercises/03.databases/04.solution.test-data/server/utils/monitoring.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/server/utils/monitoring.ts
rename to exercises/03.databases/04.solution.test-data/server/utils/monitoring.ts
diff --git a/exercises/02.test-setup/04.solution.api-mocking/tests/db-utils.ts b/exercises/03.databases/04.solution.test-data/tests/db-utils.ts
similarity index 100%
rename from exercises/02.test-setup/04.solution.api-mocking/tests/db-utils.ts
rename to exercises/03.databases/04.solution.test-data/tests/db-utils.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/e2e/notes-list.test.ts b/exercises/03.databases/04.solution.test-data/tests/e2e/notes-list.test.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/e2e/notes-list.test.ts
rename to exercises/03.databases/04.solution.test-data/tests/e2e/notes-list.test.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/e2e/utils.ts b/exercises/03.databases/04.solution.test-data/tests/e2e/utils.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/e2e/utils.ts
rename to exercises/03.databases/04.solution.test-data/tests/e2e/utils.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tests/setup/custom-matchers.ts b/exercises/03.databases/04.solution.test-data/tests/setup/custom-matchers.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tests/setup/custom-matchers.ts
rename to exercises/03.databases/04.solution.test-data/tests/setup/custom-matchers.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tests/setup/db-setup.ts b/exercises/03.databases/04.solution.test-data/tests/setup/db-setup.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tests/setup/db-setup.ts
rename to exercises/03.databases/04.solution.test-data/tests/setup/db-setup.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tests/setup/global-setup.ts b/exercises/03.databases/04.solution.test-data/tests/setup/global-setup.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tests/setup/global-setup.ts
rename to exercises/03.databases/04.solution.test-data/tests/setup/global-setup.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tests/setup/setup-test-env.ts b/exercises/03.databases/04.solution.test-data/tests/setup/setup-test-env.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tests/setup/setup-test-env.ts
rename to exercises/03.databases/04.solution.test-data/tests/setup/setup-test-env.ts
diff --git a/exercises/02.test-setup/05.solution.test-data/tests/test-extend.ts b/exercises/03.databases/04.solution.test-data/tests/test-extend.ts
similarity index 100%
rename from exercises/02.test-setup/05.solution.test-data/tests/test-extend.ts
rename to exercises/03.databases/04.solution.test-data/tests/test-extend.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tests/utils.ts b/exercises/03.databases/04.solution.test-data/tests/utils.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tests/utils.ts
rename to exercises/03.databases/04.solution.test-data/tests/utils.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/tsconfig.json b/exercises/03.databases/04.solution.test-data/tsconfig.json
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/tsconfig.json
rename to exercises/03.databases/04.solution.test-data/tsconfig.json
diff --git a/exercises/03.guides/01.problem.recording-interactions/types/deps.d.ts b/exercises/03.databases/04.solution.test-data/types/deps.d.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/types/deps.d.ts
rename to exercises/03.databases/04.solution.test-data/types/deps.d.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/types/env.env.d.ts b/exercises/03.databases/04.solution.test-data/types/env.env.d.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/types/env.env.d.ts
rename to exercises/03.databases/04.solution.test-data/types/env.env.d.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/types/icon-name.d.ts b/exercises/03.databases/04.solution.test-data/types/icon-name.d.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/types/icon-name.d.ts
rename to exercises/03.databases/04.solution.test-data/types/icon-name.d.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/types/reset.d.ts b/exercises/03.databases/04.solution.test-data/types/reset.d.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/types/reset.d.ts
rename to exercises/03.databases/04.solution.test-data/types/reset.d.ts
diff --git a/exercises/03.guides/01.problem.recording-interactions/vite.config.ts b/exercises/03.databases/04.solution.test-data/vite.config.ts
similarity index 100%
rename from exercises/03.guides/01.problem.recording-interactions/vite.config.ts
rename to exercises/03.databases/04.solution.test-data/vite.config.ts
diff --git a/exercises/03.databases/FINISHED.mdx b/exercises/03.databases/FINISHED.mdx
new file mode 100644
index 0000000..602f6d8
--- /dev/null
+++ b/exercises/03.databases/FINISHED.mdx
@@ -0,0 +1 @@
+# Databases
\ No newline at end of file
diff --git a/exercises/03.databases/README.mdx b/exercises/03.databases/README.mdx
new file mode 100644
index 0000000..91a5ce6
--- /dev/null
+++ b/exercises/03.databases/README.mdx
@@ -0,0 +1,3 @@
+# Databases
+
+- Show how to setup your tests for applications that use different database types.
diff --git a/exercises/03.guides/01.solution.recording-interactions/package.json b/exercises/03.guides/01.solution.recording-interactions/package.json
deleted file mode 100644
index 000ce83..0000000
--- a/exercises/03.guides/01.solution.recording-interactions/package.json
+++ /dev/null
@@ -1,171 +0,0 @@
-{
- "name": "exercises_03.guides_01.solution.recording-interactions",
- "private": true,
- "sideEffects": false,
- "type": "module",
- "imports": {
- "#app/*": "./app/*",
- "#tests/*": "./tests/*"
- },
- "scripts": {
- "build": "run-s build:*",
- "build:remix": "react-router build",
- "build:server": "tsx ./other/build-server.ts",
- "dev": "cross-env NODE_ENV=development MOCKS=true node ./server/dev-server.js",
- "dev:no-mocks": "cross-env NODE_ENV=development node ./server/dev-server.js",
- "format": "prettier --write .",
- "lint": "eslint .",
- "setup": "npm run build && prisma migrate deploy && prisma generate --sql && playwright install",
- "start": "cross-env NODE_ENV=production node .",
- "start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .",
- "test": "npx playwright test",
- "coverage": "vitest run --coverage",
- "test:e2e": "npm run test:e2e:dev --silent",
- "test:e2e:dev": "npx playwright test --ui",
- "pretest:e2e:run": "npm run build",
- "test:e2e:run": "npx cross-env CI=true npx playwright test",
- "test:e2e:install": "npx playwright install --with-deps chromium",
- "typecheck": "react-router typegen && tsc",
- "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run",
- "post:playground": "npx react-router typegen && prisma migrate deploy && prisma generate --sql"
- },
- "prettier": "@epic-web/config/prettier",
- "eslintIgnore": [
- "/node_modules",
- "/build",
- "/public/build",
- "/playwright-report",
- "/server-build"
- ],
- "dependencies": {
- "@conform-to/react": "^1.5.0",
- "@conform-to/zod": "^1.5.0",
- "@epic-web/cachified": "^5.5.2",
- "@epic-web/client-hints": "^1.3.5",
- "@epic-web/invariant": "^1.0.0",
- "@epic-web/remember": "^1.1.0",
- "@epic-web/totp": "^4.0.1",
- "@mjackson/form-data-parser": "^0.7.0",
- "@mjackson/headers": "^0.10.0",
- "@nasa-gcn/remix-seo": "^2.0.1",
- "@nichtsam/helmet": "^0.3.1",
- "@oslojs/crypto": "^1.0.1",
- "@oslojs/encoding": "^1.1.0",
- "@paralleldrive/cuid2": "^2.2.2",
- "@prisma/client": "^6.7.0",
- "@prisma/instrumentation": "^6.7.0",
- "@radix-ui/react-checkbox": "^1.2.3",
- "@radix-ui/react-dropdown-menu": "^2.1.12",
- "@radix-ui/react-label": "^2.1.4",
- "@radix-ui/react-slot": "^1.2.0",
- "@radix-ui/react-toast": "^1.2.11",
- "@radix-ui/react-tooltip": "^1.2.4",
- "@react-email/components": "0.0.38",
- "@react-router/express": "^7.5.3",
- "@react-router/node": "^7.5.3",
- "@react-router/remix-routes-option-adapter": "^7.5.3",
- "@remix-run/server-runtime": "^2.16.5",
- "@sentry/profiling-node": "^9.32.0",
- "@sentry/react-router": "^9.32.0",
- "@simplewebauthn/browser": "^13.1.0",
- "@simplewebauthn/server": "^13.1.1",
- "@tailwindcss/vite": "^4.1.5",
- "@tusbar/cache-control": "1.0.2",
- "address": "^2.0.3",
- "bcryptjs": "^3.0.2",
- "class-variance-authority": "^0.7.1",
- "close-with-grace": "^2.2.0",
- "clsx": "^2.1.1",
- "compression": "^1.8.0",
- "cookie": "^1.0.2",
- "cross-env": "^7.0.3",
- "date-fns": "^4.1.0",
- "dotenv": "^16.5.0",
- "execa": "^9.5.2",
- "express": "^4.21.2",
- "express-rate-limit": "^7.5.0",
- "get-port": "^7.1.0",
- "glob": "^11.0.2",
- "input-otp": "^1.4.2",
- "intl-parse-accept-language": "^1.0.0",
- "isbot": "^5.1.27",
- "litefs-js": "^2.0.2",
- "lru-cache": "^11.1.0",
- "mime-types": "^3.0.1",
- "morgan": "^1.10.0",
- "openimg": "^1.1.0",
- "prisma": "^6.7.0",
- "qrcode": "^1.5.4",
- "react": "^19.1.0",
- "react-dom": "^19.1.0",
- "react-router": "^7.5.3",
- "remix-auth": "^4.2.0",
- "remix-auth-github": "^3.0.2",
- "remix-utils": "^8.5.0",
- "set-cookie-parser": "^2.7.1",
- "sharp": "^0.34.2",
- "sonner": "^2.0.3",
- "source-map-support": "^0.5.21",
- "spin-delay": "^2.0.1",
- "tailwind-merge": "^3.2.0",
- "tailwindcss": "^4.1.5",
- "vite-env-only": "^3.0.3",
- "zod": "^3.24.4"
- },
- "devDependencies": {
- "@epic-web/config": "^1.20.1",
- "@faker-js/faker": "^9.7.0",
- "@playwright/test": "^1.52.0",
- "@react-router/dev": "^7.5.3",
- "@sly-cli/sly": "^2.1.1",
- "@testing-library/dom": "^10.4.0",
- "@testing-library/jest-dom": "^6.6.3",
- "@testing-library/react": "^16.3.0",
- "@testing-library/user-event": "^14.6.1",
- "@total-typescript/ts-reset": "^0.6.1",
- "@types/compression": "^1.7.5",
- "@types/eslint": "^9.6.1",
- "@types/express": "^4.17.21",
- "@types/fs-extra": "^11.0.4",
- "@types/glob": "^8.1.0",
- "@types/mime-types": "^2.1.4",
- "@types/morgan": "^1.9.9",
- "@types/node": "^22.15.3",
- "@types/qrcode": "^1.5.5",
- "@types/react": "^19.1.2",
- "@types/react-dom": "^19.1.3",
- "@types/set-cookie-parser": "^2.4.10",
- "@types/source-map-support": "^0.5.10",
- "@vitejs/plugin-react": "^4.4.1",
- "@vitest/coverage-v8": "^3.1.3",
- "enforce-unique": "^1.3.0",
- "esbuild": "^0.25.3",
- "eslint": "^9.26.0",
- "fs-extra": "^11.3.0",
- "jsdom": "^25.0.1",
- "msw": "^2.7.6",
- "npm-run-all": "^4.1.5",
- "playwright-persona": "^0.2.5",
- "prettier": "^3.5.3",
- "prettier-plugin-sql": "^0.19.0",
- "prettier-plugin-tailwindcss": "^0.6.11",
- "react-router-devtools": "^5.0.5",
- "remix-flat-routes": "^0.8.5",
- "tsx": "^4.19.4",
- "tw-animate-css": "^1.2.9",
- "typescript": "^5.8.3",
- "vite": "^6.3.5",
- "vite-plugin-icons-spritesheet": "^3.0.1",
- "vitest": "^3.1.3"
- },
- "engines": {
- "node": "22.14.0"
- },
- "prisma": {
- "seed": "tsx prisma/seed.ts"
- },
- "epic-stack": {
- "head": "4e6532d08219cef41299615ad7556b205aa0b77d",
- "date": "2025-07-02T03:11:12Z"
- }
-}
diff --git a/exercises/03.guides/02.problem.test-annotations/README.mdx b/exercises/03.guides/02.problem.test-annotations/README.mdx
deleted file mode 100644
index 47723f6..0000000
--- a/exercises/03.guides/02.problem.test-annotations/README.mdx
+++ /dev/null
@@ -1,88 +0,0 @@
-# Test annotations
-
-## Your task
-
-👨💼 In this one, your task is to use [Annotations](https://playwright.dev/docs/test-annotations) in Playwright to improve the developer experience of your test suite. You will focus on two types of annotations today: _tags_ and _custom annotations_. Please follow the steps below.
-
-### Tags
-
-Let's start with the tags. You can add a tag to any test case by providing a test details object as the second argument of your test case (after the test name but before the test callback) and specifying the `tag` property in that object:
-
-```ts highlight=3-5
-test(
- 'displays a user greeting',
- {
- tag: ['@user'],
- },
- async ({ page }) => {},
-)
-```
-
-🐨 Equipped with this knowledge, head to the following test cases and mark them with their respective tags:
-
-| Test file | Test case | Tags |
-| ------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------- |
-| `tests/e2e/homepage.test.ts` | "creates a new note" | `@homepage` |
-| `tests/e2e/notes-create.test.ts` | "creates a new note" | `@user`, `@notes` |
-| `tests/e2e/profile-edit.test.ts` | "displays the user profile page" | `@user`, `@profile` |
-| `tests/e2e/profile-edit.test.ts` | "saves changes to the name of the user" | `@user`, `@profile` |
-
-Note that tags in Playwright _must_ begin with an at sign "@" (e.g. `@user`, `@dashboard`, etc).
-
-🐨 Once you've marked those tests with their tags, try running a subset of your test suite based on a tag. For example, to run only the test cases realted to the user profile, include its tag `@profile` as the value of the `--grep` option of Playwright's CLI:
-
-```sh
-npx playwright test --grep=@profile
-```
-
-You can use tags to filter out tests and test reports as well. Explore them in the UI mode as well as in the test report (`npx playwright show-report`).
-
-### Custom annotations
-
-Now, it's time for you to improve the failure experience of your tests. One of the ways to do that is by including additional data next to individual test cases. That data is referred to as "annotations" in Playwright. Each annotation allows you to define its `type` and `description`, and is defined in the test details object as well:
-
-```ts highlight=3-8
-test(
- 'displays a user greeting',
- {
- annotation: {
- type: 'issue',
- description: 'https://epicweb.dev/',
- },
- },
- async ({ page }) => {},
-)
-```
-
-Let's use annotations in action!
-
-🐨 First, run the test cases for the homepage, using the `@homepage` tag you've defined earlier. Once you do that, you will see a test case failing:
-
-```
-Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
-
-Locator: getByRole('heading', { name: 'The Most Epic of Stacks' })
-Expected: visible
-Received:
-Call log:
- - Expect "toBeVisible" with timeout 5000ms
- - waiting for getByRole('heading', { name: 'The Most Epic of Stacks' })
-
-
- 6 | await expect(
- 7 | page.getByRole('heading', { name: 'The Most Epic of Stacks' }),
-> 8 | ).toBeVisible()
- | ^
- 9 | })
- 10 |
-```
-
-It looks like it cannot find the given element on the page! Actually, I think I've had this issue before. Yeah, definitely, there's even a [GitHub issue about it](https://github.com/epicweb-dev/epic-stack/issues/1020).
-
-🐨 Before you fix the problem, annotate this failing test, providing `issue` as the annotation's type and the GitHub issue URL I've linked above as the annotation's description.
-
-Annotating your tests helps you (and your colleagues) debug and fix them faster when they fail. The more context you have on the issue, the more efficient you are as a developer.
-
-🐨 Try re-running the same test again. If you preview the test report via `npx playwright show-report`, you will now spot your custom annotation right above the test result!
-
-🐨 Read through the [GitHub issue](https://github.com/epicweb-dev/epic-stack/issues/1020) and see if you can find any recommendations on how to fix this failing test. Once you do, fix it and have it passing again.
diff --git a/exercises/03.guides/02.problem.test-annotations/tests/e2e/homepage.test.ts b/exercises/03.guides/02.problem.test-annotations/tests/e2e/homepage.test.ts
deleted file mode 100644
index 34f0cd4..0000000
--- a/exercises/03.guides/02.problem.test-annotations/tests/e2e/homepage.test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { test, expect } from '#tests/test-extend'
-
-// 🐨 Add a test details object as the second argument to the "test" function.
-// 💰 test(title, details, callback)
-//
-// 🐨 In the test details object, specify a key called "tag".
-// As the value for that key, provide an array with a single tag "@homepage".
-// 💰 { tag: ['@tagName'] }
-test('displays the welcome heading', async ({ navigate, page }) => {
- await navigate('/')
-
- await expect(
- page.getByRole('heading', { name: 'The Most Epic of Stacks' }),
- ).toBeVisible()
-})
diff --git a/exercises/03.guides/02.problem.test-annotations/tests/e2e/notes-create.test.ts b/exercises/03.guides/02.problem.test-annotations/tests/e2e/notes-create.test.ts
deleted file mode 100644
index c72bd55..0000000
--- a/exercises/03.guides/02.problem.test-annotations/tests/e2e/notes-create.test.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { test, expect } from '#tests/test-extend.ts'
-
-// 🐨 Add a test details object as the second argument to the "test" function.
-// 💰 test(title, details, callback)
-//
-// 🐨 In the test details object, specify a key called "tag".
-// As the value for that key, provide an array with the tags "@user" and "@notes".
-// 💰 { tag: ['@oneTag', "@anotherTag"] }
-test('creates a new note', async ({ navigate, authenticate, page }) => {
- const { user } = await authenticate({ as: 'user' })
-
- await navigate('/users/:username/notes/new', { username: user.username })
-
- await page.getByLabel('Title').fill('My new note')
- await page.getByLabel('Content').fill('Hello world')
- await page.getByRole('button', { name: 'Submit' }).click()
-
- await expect(page.getByRole('heading', { name: 'My new note' })).toBeVisible()
- await expect(
- page.getByLabel('My new note').getByText('Hello world'),
- ).toBeVisible()
-})
diff --git a/exercises/03.guides/02.problem.test-annotations/tests/e2e/profile-edit.test.ts b/exercises/03.guides/02.problem.test-annotations/tests/e2e/profile-edit.test.ts
deleted file mode 100644
index 1bfafbe..0000000
--- a/exercises/03.guides/02.problem.test-annotations/tests/e2e/profile-edit.test.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { test, expect } from '#tests/test-extend.ts'
-
-// 🐨 Add a test details object as the second argument to the "test" function.
-// 💰 test(title, details, callback)
-//
-// 🐨 In the test details object, specify a key called "tag".
-// As the value for that key, provide an array with the tags "@user" and "@profile".
-// 💰 { tag: ['@oneTag', "@anotherTag"] }
-test('displays the user profile page', async ({
- authenticate,
- navigate,
- page,
-}) => {
- const { user } = await authenticate({ as: 'user' })
- await navigate('/users/:username', { username: user.username })
-
- await expect(page.getByRole('heading', { name: user.name! })).toBeVisible()
- await expect(page.getByRole('button', { name: 'Logout' })).toBeVisible()
- await expect(page.getByRole('link', { name: 'My notes' })).toBeVisible()
- await expect(page.getByRole('link', { name: 'Edit profile' })).toBeVisible()
-})
-
-// 🐨 Provide the same tags "@user" and "@profile" for this test case as well.
-test(
- 'saves changes to the name of the user',
- {
- tag: ['@user', '@profile'],
- },
- async ({ authenticate, navigate, page }) => {
- await authenticate({ as: 'user' })
- await navigate('/settings/profile')
-
- await page.getByRole('textbox', { name: 'Username' }).click()
- await page
- .getByRole('textbox', { name: 'Username' })
- .press('ControlOrMeta+a')
- await page.getByRole('textbox', { name: 'Username' }).fill('new_username')
- await page.getByRole('button', { name: 'Save changes' }).click()
-
- await expect(page.getByRole('textbox', { name: 'Username' })).toBeVisible()
- },
-)
diff --git a/exercises/03.guides/02.solution.test-annotations/README.mdx b/exercises/03.guides/02.solution.test-annotations/README.mdx
deleted file mode 100644
index 55d8bfe..0000000
--- a/exercises/03.guides/02.solution.test-annotations/README.mdx
+++ /dev/null
@@ -1,31 +0,0 @@
-# Test annotations
-
-Good job! 👏
-
-Please wait for the others to finish so we could go through the solution to this exercise together.
-
----
-
-Things you can do with tags:
-
-1. Run a subset of tests:
-
-```sh
-npm test -- --grep=@user
-npm test -- --grep=@user|@profile
-```
-
-2. You can also filter and run subset of tests from the UI mode (the "Filter" input at the top left).
-3. You can filter the test results in the test report (`show-report`) by tags.
-
-Things you can do with annotations:
-
-```sh
-npx playwright show-report
-# And then click on the failing test.
-# Custom annotataions will list extra info to help you debug.
-```
-
-## Related materials
-
-- [Test annotations](https://playwright.dev/docs/test-annotations)
diff --git a/exercises/03.guides/02.solution.test-annotations/tests/e2e/homepage.test.ts b/exercises/03.guides/02.solution.test-annotations/tests/e2e/homepage.test.ts
deleted file mode 100644
index ea6d137..0000000
--- a/exercises/03.guides/02.solution.test-annotations/tests/e2e/homepage.test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { test, expect } from '#tests/test-extend'
-
-test(
- 'displays the welcome heading',
- {
- tag: ['@homepage'],
- annotation: {
- type: 'issue',
- description: 'https://github.com/epicweb-dev/epic-stack/issues/1020',
- },
- },
- async ({ navigate, page }) => {
- await navigate('/')
-
- await expect(
- page.getByRole('heading', { name: 'The Epic Stack' }),
- ).toBeVisible()
- },
-)
diff --git a/exercises/03.guides/02.solution.test-annotations/tests/e2e/notes-create.test.ts b/exercises/03.guides/02.solution.test-annotations/tests/e2e/notes-create.test.ts
deleted file mode 100644
index a6b0f43..0000000
--- a/exercises/03.guides/02.solution.test-annotations/tests/e2e/notes-create.test.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { test, expect } from '#tests/test-extend.ts'
-
-test(
- 'creates a new note',
- {
- tag: ['@user', '@notes'],
- },
- async ({ navigate, authenticate, page }) => {
- const { user } = await authenticate({ as: 'user' })
-
- await navigate('/users/:username/notes/new', { username: user.username })
-
- await page.getByLabel('Title').fill('My new note')
- await page.getByLabel('Content').fill('Hello world')
- await page.getByRole('button', { name: 'Submit' }).click()
-
- await expect(
- page.getByRole('heading', { name: 'My new note' }),
- ).toBeVisible()
- await expect(
- page.getByLabel('My new note').getByText('Hello world'),
- ).toBeVisible()
- },
-)
diff --git a/exercises/03.guides/02.solution.test-annotations/tests/e2e/profile-edit.test.ts b/exercises/03.guides/02.solution.test-annotations/tests/e2e/profile-edit.test.ts
deleted file mode 100644
index ea932cc..0000000
--- a/exercises/03.guides/02.solution.test-annotations/tests/e2e/profile-edit.test.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { test, expect } from '#tests/test-extend.ts'
-
-test(
- 'displays the user profile page',
- {
- tag: ['@user', '@profile'],
- },
- async ({ authenticate, navigate, page }) => {
- const { user } = await authenticate({ as: 'user' })
- await navigate('/users/:username', { username: user.username })
-
- await expect(page.getByRole('heading', { name: user.name! })).toBeVisible()
- await expect(page.getByRole('button', { name: 'Logout' })).toBeVisible()
- await expect(page.getByRole('link', { name: 'My notes' })).toBeVisible()
- await expect(page.getByRole('link', { name: 'Edit profile' })).toBeVisible()
- },
-)
-
-test(
- 'saves changes to the name of the user',
- {
- tag: ['@user', '@profile'],
- },
- async ({ authenticate, navigate, page }) => {
- await authenticate({ as: 'user' })
- await navigate('/settings/profile')
-
- await page.getByRole('textbox', { name: 'Username' }).click()
- await page
- .getByRole('textbox', { name: 'Username' })
- .press('ControlOrMeta+a')
- await page.getByRole('textbox', { name: 'Username' }).fill('new_username')
- await page.getByRole('button', { name: 'Save changes' }).click()
-
- await expect(page.getByRole('textbox', { name: 'Username' })).toBeVisible()
- },
-)
diff --git a/exercises/03.guides/03.problem.blocking-unneeded-requests/README.mdx b/exercises/03.guides/03.problem.blocking-unneeded-requests/README.mdx
deleted file mode 100644
index ecd79cd..0000000
--- a/exercises/03.guides/03.problem.blocking-unneeded-requests/README.mdx
+++ /dev/null
@@ -1,27 +0,0 @@
-# Blocking unneeded requests
-
-Our application now has [One Dollar Stats](https://onedollarstats.com/) for very simple analytics. That's useful in production but we don't need this analytics script running in our tests. It only creates unnecessary requests and takes time.
-
-Let's block this kind of requests in Playwright!
-
-## Your task
-
-👨💼 In this one, your task is to block a certain HTTP request fired by the app. I'm talking about this analytics script:
-
-```jsx
-
-```
-
-🐨 Go to the `tests/test-extend.ts` file and follow the instructions to intercept the problematic request and handle its response.
-
-🐨 Finally, it would be great to verify your solution and make sure that the request in question indeed receives a mocked response during the test. To do that, run your tests in a UI mode:
-
-```sh
-npm test -- --ui
-```
-
-In the UI mode window, open the "Network" tab and find the request that you have intercepted (`GET /stonks.js`). You should see it having a mocked response!
diff --git a/exercises/03.guides/03.problem.blocking-unneeded-requests/package.json b/exercises/03.guides/03.problem.blocking-unneeded-requests/package.json
deleted file mode 100644
index ff892f4..0000000
--- a/exercises/03.guides/03.problem.blocking-unneeded-requests/package.json
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- "name": "exercises_03.guides_03.problem.blocking-unneeded-requests",
- "private": true,
- "sideEffects": false,
- "type": "module",
- "imports": {
- "#app/*": "./app/*",
- "#tests/*": "./tests/*"
- },
- "scripts": {
- "build": "run-s build:*",
- "build:remix": "react-router build",
- "build:server": "tsx ./other/build-server.ts",
- "dev": "cross-env NODE_ENV=development MOCKS=true node ./server/dev-server.js",
- "dev:no-mocks": "cross-env NODE_ENV=development node ./server/dev-server.js",
- "format": "prettier --write .",
- "lint": "eslint .",
- "setup": "npm run build && prisma migrate deploy && prisma generate --sql && playwright install",
- "start": "cross-env NODE_ENV=production node .",
- "start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .",
- "test": "npx playwright test",
- "coverage": "vitest run --coverage",
- "test:e2e": "npm run test:e2e:dev --silent",
- "test:e2e:dev": "npx playwright test --ui",
- "pretest:e2e:run": "npm run build",
- "test:e2e:run": "npx cross-env CI=true npx playwright test",
- "test:e2e:install": "npx playwright install --with-deps chromium",
- "typecheck": "react-router typegen && tsc",
- "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run",
- "post:playground": "npx react-router typegen && prisma migrate deploy && prisma generate --sql"
- },
- "prettier": "@epic-web/config/prettier",
- "eslintIgnore": [
- "/node_modules",
- "/build",
- "/public/build",
- "/playwright-report",
- "/server-build"
- ],
- "dependencies": {
- "@conform-to/react": "^1.5.0",
- "@conform-to/zod": "^1.5.0",
- "@epic-web/cachified": "^5.5.2",
- "@epic-web/client-hints": "^1.3.5",
- "@epic-web/invariant": "^1.0.0",
- "@epic-web/remember": "^1.1.0",
- "@epic-web/totp": "^4.0.1",
- "@mjackson/form-data-parser": "^0.7.0",
- "@mjackson/headers": "^0.10.0",
- "@nasa-gcn/remix-seo": "^2.0.1",
- "@nichtsam/helmet": "^0.3.1",
- "@oslojs/crypto": "^1.0.1",
- "@oslojs/encoding": "^1.1.0",
- "@paralleldrive/cuid2": "^2.2.2",
- "@prisma/client": "^6.7.0",
- "@prisma/instrumentation": "^6.7.0",
- "@radix-ui/react-checkbox": "^1.2.3",
- "@radix-ui/react-dropdown-menu": "^2.1.12",
- "@radix-ui/react-label": "^2.1.4",
- "@radix-ui/react-slot": "^1.2.0",
- "@radix-ui/react-toast": "^1.2.11",
- "@radix-ui/react-tooltip": "^1.2.4",
- "@react-email/components": "0.0.38",
- "@react-router/express": "^7.5.3",
- "@react-router/node": "^7.5.3",
- "@react-router/remix-routes-option-adapter": "^7.5.3",
- "@remix-run/server-runtime": "^2.16.5",
- "@sentry/profiling-node": "^9.32.0",
- "@sentry/react-router": "^9.32.0",
- "@simplewebauthn/browser": "^13.1.0",
- "@simplewebauthn/server": "^13.1.1",
- "@tailwindcss/vite": "^4.1.5",
- "@tusbar/cache-control": "1.0.2",
- "address": "^2.0.3",
- "bcryptjs": "^3.0.2",
- "class-variance-authority": "^0.7.1",
- "close-with-grace": "^2.2.0",
- "clsx": "^2.1.1",
- "compression": "^1.8.0",
- "cookie": "^1.0.2",
- "cross-env": "^7.0.3",
- "date-fns": "^4.1.0",
- "dotenv": "^16.5.0",
- "execa": "^9.5.2",
- "express": "^4.21.2",
- "express-rate-limit": "^7.5.0",
- "get-port": "^7.1.0",
- "glob": "^11.0.2",
- "input-otp": "^1.4.2",
- "intl-parse-accept-language": "^1.0.0",
- "isbot": "^5.1.27",
- "litefs-js": "^2.0.2",
- "lru-cache": "^11.1.0",
- "mime-types": "^3.0.1",
- "morgan": "^1.10.0",
- "openimg": "^1.1.0",
- "prisma": "^6.7.0",
- "qrcode": "^1.5.4",
- "react": "^19.1.0",
- "react-dom": "^19.1.0",
- "react-router": "^7.5.3",
- "remix-auth": "^4.2.0",
- "remix-auth-github": "^3.0.2",
- "remix-utils": "^8.5.0",
- "set-cookie-parser": "^2.7.1",
- "sharp": "^0.34.2",
- "sonner": "^2.0.3",
- "source-map-support": "^0.5.21",
- "spin-delay": "^2.0.1",
- "tailwind-merge": "^3.2.0",
- "tailwindcss": "^4.1.5",
- "vite-env-only": "^3.0.3",
- "zod": "^3.24.4"
- },
- "devDependencies": {
- "@epic-web/config": "^1.20.1",
- "@faker-js/faker": "^9.7.0",
- "@msw/playwright": "^0.4.2",
- "@playwright/test": "^1.52.0",
- "@react-router/dev": "^7.5.3",
- "@sly-cli/sly": "^2.1.1",
- "@testing-library/dom": "^10.4.0",
- "@testing-library/jest-dom": "^6.6.3",
- "@testing-library/react": "^16.3.0",
- "@testing-library/user-event": "^14.6.1",
- "@total-typescript/ts-reset": "^0.6.1",
- "@types/compression": "^1.7.5",
- "@types/eslint": "^9.6.1",
- "@types/express": "^4.17.21",
- "@types/fs-extra": "^11.0.4",
- "@types/glob": "^8.1.0",
- "@types/mime-types": "^2.1.4",
- "@types/morgan": "^1.9.9",
- "@types/node": "^22.15.3",
- "@types/qrcode": "^1.5.5",
- "@types/react": "^19.1.2",
- "@types/react-dom": "^19.1.3",
- "@types/set-cookie-parser": "^2.4.10",
- "@types/source-map-support": "^0.5.10",
- "@vitejs/plugin-react": "^4.4.1",
- "@vitest/coverage-v8": "^3.1.3",
- "enforce-unique": "^1.3.0",
- "esbuild": "^0.25.3",
- "eslint": "^9.26.0",
- "fs-extra": "^11.3.0",
- "jsdom": "^25.0.1",
- "msw": "^2.7.6",
- "npm-run-all": "^4.1.5",
- "playwright-persona": "^0.2.5",
- "prettier": "^3.5.3",
- "prettier-plugin-sql": "^0.19.0",
- "prettier-plugin-tailwindcss": "^0.6.11",
- "react-router-devtools": "^5.0.5",
- "remix-flat-routes": "^0.8.5",
- "tsx": "^4.19.4",
- "tw-animate-css": "^1.2.9",
- "typescript": "^5.8.3",
- "vite": "^6.3.5",
- "vite-plugin-icons-spritesheet": "^3.0.1",
- "vitest": "^3.1.3"
- },
- "engines": {
- "node": "22.14.0"
- },
- "prisma": {
- "seed": "tsx prisma/seed.ts"
- },
- "epic-stack": {
- "head": "4e6532d08219cef41299615ad7556b205aa0b77d",
- "date": "2025-07-02T03:11:12Z"
- }
-}
diff --git a/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/e2e/homepage.test.ts b/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/e2e/homepage.test.ts
deleted file mode 100644
index b7c8d34..0000000
--- a/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/e2e/homepage.test.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { test, expect } from '#tests/test-extend'
-
-test('displays the welcome heading', async ({ navigate, page }) => {
- await navigate('/')
-
- await expect(
- page.getByRole('heading', { name: 'The Epic Stack' }),
- ).toBeVisible()
-})
diff --git a/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/test-extend.ts b/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/test-extend.ts
deleted file mode 100644
index 597ae96..0000000
--- a/exercises/03.guides/03.problem.blocking-unneeded-requests/tests/test-extend.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { createNetworkFixture, type NetworkFixture } from '@msw/playwright'
-import { test as testBase, expect } from '@playwright/test'
-// 🐨 Imoprt the `http` object and the `HttpResponse` class from "msw".
-// 💰 import { this, that } from 'package'
-import {
- definePersona,
- combinePersonas,
- type AuthenticateFunction,
-} from 'playwright-persona'
-import { href, type Register } from 'react-router'
-import { getPasswordHash } from '#app/utils/auth.server.ts'
-import { prisma } from '#app/utils/db.server.ts'
-import { createUser } from '#tests/db-utils'
-
-interface Fixtures {
- navigate: (
- ...args: Parameters>
- ) => Promise
- authenticate: AuthenticateFunction<[typeof user]>
- network: NetworkFixture
-}
-
-const user = definePersona('user', {
- async createSession({ page }) {
- const user = await prisma.user.create({
- data: {
- ...createUser(),
- roles: { connect: { name: 'user' } },
- password: { create: { hash: await getPasswordHash('supersecret') } },
- },
- })
-
- await page.goto('/login')
- await page.getByLabel('Username').fill(user.username)
- await page.getByLabel('Password').fill('supersecret')
- await page.getByRole('button', { name: 'Log in' }).click()
- await page.getByText(user.name!).waitFor({ state: 'visible' })
-
- return { user }
- },
- async verifySession({ page, session }) {
- await page.goto('/')
- await expect(page.getByText(session.user.name!)).toBeVisible({
- timeout: 100,
- })
- },
- async destroySession({ session }) {
- await prisma.user.deleteMany({ where: { id: session.user.id } })
- },
-})
-
-export const test = testBase.extend({
- async navigate({ page }, use) {
- await use(async (...args) => {
- await page.goto(href(...args))
- })
- },
- authenticate: combinePersonas(user),
- network: createNetworkFixture({
- initialHandlers: [
- // 🐨 Add a new handler for a GET request to the "https://assets.onedollarstats.com" URL.
- // Capture all the requests to that URL by using a wildcard "*".
- // 💰 http.get(path, resolver)
- //
- // 🐨 In the resolver for that handler, return an empty response.
- // 💰 new HttpResponse()
- ],
- }),
-})
-
-export { expect }
diff --git a/exercises/03.guides/03.solution.blocking-unneeded-requests/README.mdx b/exercises/03.guides/03.solution.blocking-unneeded-requests/README.mdx
deleted file mode 100644
index 9a4e527..0000000
--- a/exercises/03.guides/03.solution.blocking-unneeded-requests/README.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-# Blocking unneeded requests
-
-Good job! 👏
-
-Please wait for the others to finish so we could go through the solution to this exercise together.
diff --git a/exercises/03.guides/03.solution.blocking-unneeded-requests/package.json b/exercises/03.guides/03.solution.blocking-unneeded-requests/package.json
deleted file mode 100644
index 6128622..0000000
--- a/exercises/03.guides/03.solution.blocking-unneeded-requests/package.json
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- "name": "exercises_03.guides_03.solution.blocking-unneeded-requests",
- "private": true,
- "sideEffects": false,
- "type": "module",
- "imports": {
- "#app/*": "./app/*",
- "#tests/*": "./tests/*"
- },
- "scripts": {
- "build": "run-s build:*",
- "build:remix": "react-router build",
- "build:server": "tsx ./other/build-server.ts",
- "dev": "cross-env NODE_ENV=development MOCKS=true node ./server/dev-server.js",
- "dev:no-mocks": "cross-env NODE_ENV=development node ./server/dev-server.js",
- "format": "prettier --write .",
- "lint": "eslint .",
- "setup": "npm run build && prisma migrate deploy && prisma generate --sql && playwright install",
- "start": "cross-env NODE_ENV=production node .",
- "start:mocks": "cross-env NODE_ENV=production MOCKS=true tsx .",
- "test": "npx playwright test",
- "coverage": "vitest run --coverage",
- "test:e2e": "npm run test:e2e:dev --silent",
- "test:e2e:dev": "npx playwright test --ui",
- "pretest:e2e:run": "npm run build",
- "test:e2e:run": "npx cross-env CI=true npx playwright test",
- "test:e2e:install": "npx playwright install --with-deps chromium",
- "typecheck": "react-router typegen && tsc",
- "validate": "run-p \"test -- --run\" lint typecheck test:e2e:run",
- "post:playground": "npx react-router typegen && prisma migrate deploy && prisma generate --sql"
- },
- "prettier": "@epic-web/config/prettier",
- "eslintIgnore": [
- "/node_modules",
- "/build",
- "/public/build",
- "/playwright-report",
- "/server-build"
- ],
- "dependencies": {
- "@conform-to/react": "^1.5.0",
- "@conform-to/zod": "^1.5.0",
- "@epic-web/cachified": "^5.5.2",
- "@epic-web/client-hints": "^1.3.5",
- "@epic-web/invariant": "^1.0.0",
- "@epic-web/remember": "^1.1.0",
- "@epic-web/totp": "^4.0.1",
- "@mjackson/form-data-parser": "^0.7.0",
- "@mjackson/headers": "^0.10.0",
- "@nasa-gcn/remix-seo": "^2.0.1",
- "@nichtsam/helmet": "^0.3.1",
- "@oslojs/crypto": "^1.0.1",
- "@oslojs/encoding": "^1.1.0",
- "@paralleldrive/cuid2": "^2.2.2",
- "@prisma/client": "^6.7.0",
- "@prisma/instrumentation": "^6.7.0",
- "@radix-ui/react-checkbox": "^1.2.3",
- "@radix-ui/react-dropdown-menu": "^2.1.12",
- "@radix-ui/react-label": "^2.1.4",
- "@radix-ui/react-slot": "^1.2.0",
- "@radix-ui/react-toast": "^1.2.11",
- "@radix-ui/react-tooltip": "^1.2.4",
- "@react-email/components": "0.0.38",
- "@react-router/express": "^7.5.3",
- "@react-router/node": "^7.5.3",
- "@react-router/remix-routes-option-adapter": "^7.5.3",
- "@remix-run/server-runtime": "^2.16.5",
- "@sentry/profiling-node": "^9.32.0",
- "@sentry/react-router": "^9.32.0",
- "@simplewebauthn/browser": "^13.1.0",
- "@simplewebauthn/server": "^13.1.1",
- "@tailwindcss/vite": "^4.1.5",
- "@tusbar/cache-control": "1.0.2",
- "address": "^2.0.3",
- "bcryptjs": "^3.0.2",
- "class-variance-authority": "^0.7.1",
- "close-with-grace": "^2.2.0",
- "clsx": "^2.1.1",
- "compression": "^1.8.0",
- "cookie": "^1.0.2",
- "cross-env": "^7.0.3",
- "date-fns": "^4.1.0",
- "dotenv": "^16.5.0",
- "execa": "^9.5.2",
- "express": "^4.21.2",
- "express-rate-limit": "^7.5.0",
- "get-port": "^7.1.0",
- "glob": "^11.0.2",
- "input-otp": "^1.4.2",
- "intl-parse-accept-language": "^1.0.0",
- "isbot": "^5.1.27",
- "litefs-js": "^2.0.2",
- "lru-cache": "^11.1.0",
- "mime-types": "^3.0.1",
- "morgan": "^1.10.0",
- "openimg": "^1.1.0",
- "prisma": "^6.7.0",
- "qrcode": "^1.5.4",
- "react": "^19.1.0",
- "react-dom": "^19.1.0",
- "react-router": "^7.5.3",
- "remix-auth": "^4.2.0",
- "remix-auth-github": "^3.0.2",
- "remix-utils": "^8.5.0",
- "set-cookie-parser": "^2.7.1",
- "sharp": "^0.34.2",
- "sonner": "^2.0.3",
- "source-map-support": "^0.5.21",
- "spin-delay": "^2.0.1",
- "tailwind-merge": "^3.2.0",
- "tailwindcss": "^4.1.5",
- "vite-env-only": "^3.0.3",
- "zod": "^3.24.4"
- },
- "devDependencies": {
- "@epic-web/config": "^1.20.1",
- "@faker-js/faker": "^9.7.0",
- "@msw/playwright": "^0.4.2",
- "@playwright/test": "^1.52.0",
- "@react-router/dev": "^7.5.3",
- "@sly-cli/sly": "^2.1.1",
- "@testing-library/dom": "^10.4.0",
- "@testing-library/jest-dom": "^6.6.3",
- "@testing-library/react": "^16.3.0",
- "@testing-library/user-event": "^14.6.1",
- "@total-typescript/ts-reset": "^0.6.1",
- "@types/compression": "^1.7.5",
- "@types/eslint": "^9.6.1",
- "@types/express": "^4.17.21",
- "@types/fs-extra": "^11.0.4",
- "@types/glob": "^8.1.0",
- "@types/mime-types": "^2.1.4",
- "@types/morgan": "^1.9.9",
- "@types/node": "^22.15.3",
- "@types/qrcode": "^1.5.5",
- "@types/react": "^19.1.2",
- "@types/react-dom": "^19.1.3",
- "@types/set-cookie-parser": "^2.4.10",
- "@types/source-map-support": "^0.5.10",
- "@vitejs/plugin-react": "^4.4.1",
- "@vitest/coverage-v8": "^3.1.3",
- "enforce-unique": "^1.3.0",
- "esbuild": "^0.25.3",
- "eslint": "^9.26.0",
- "fs-extra": "^11.3.0",
- "jsdom": "^25.0.1",
- "msw": "^2.7.6",
- "npm-run-all": "^4.1.5",
- "playwright-persona": "^0.2.5",
- "prettier": "^3.5.3",
- "prettier-plugin-sql": "^0.19.0",
- "prettier-plugin-tailwindcss": "^0.6.11",
- "react-router-devtools": "^5.0.5",
- "remix-flat-routes": "^0.8.5",
- "tsx": "^4.19.4",
- "tw-animate-css": "^1.2.9",
- "typescript": "^5.8.3",
- "vite": "^6.3.5",
- "vite-plugin-icons-spritesheet": "^3.0.1",
- "vitest": "^3.1.3"
- },
- "engines": {
- "node": "22.14.0"
- },
- "prisma": {
- "seed": "tsx prisma/seed.ts"
- },
- "epic-stack": {
- "head": "4e6532d08219cef41299615ad7556b205aa0b77d",
- "date": "2025-07-02T03:11:12Z"
- }
-}
diff --git a/exercises/03.guides/03.solution.blocking-unneeded-requests/tests/e2e/homepage.test.ts b/exercises/03.guides/03.solution.blocking-unneeded-requests/tests/e2e/homepage.test.ts
deleted file mode 100644
index b7c8d34..0000000
--- a/exercises/03.guides/03.solution.blocking-unneeded-requests/tests/e2e/homepage.test.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { test, expect } from '#tests/test-extend'
-
-test('displays the welcome heading', async ({ navigate, page }) => {
- await navigate('/')
-
- await expect(
- page.getByRole('heading', { name: 'The Epic Stack' }),
- ).toBeVisible()
-})
diff --git a/exercises/04.debugging/01.problem.ui-mode/.github/PULL_REQUEST_TEMPLATE.md b/exercises/04.debugging/01.problem.ui-mode/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 84a2084..0000000
--- a/exercises/04.debugging/01.problem.ui-mode/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-## Test Plan
-
-
-
-## Checklist
-
-- [ ] Tests updated
-- [ ] Docs updated
-
-## Screenshots
-
-
diff --git a/exercises/04.debugging/01.problem.ui-mode/.github/workflows/deploy.yml b/exercises/04.debugging/01.problem.ui-mode/.github/workflows/deploy.yml
deleted file mode 100644
index 49cbbad..0000000
--- a/exercises/04.debugging/01.problem.ui-mode/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,229 +0,0 @@
-name: 🚀 Deploy
-on:
- push:
- branches:
- - main
- - dev
- pull_request: {}
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-permissions:
- actions: write
- contents: read
-
-jobs:
- lint:
- name: ⬣ ESLint
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔬 Lint
- run: npm run lint
-
- typecheck:
- name: ʦ TypeScript
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔎 Type check
- run: npm run typecheck --if-present
-
- vitest:
- name: ⚡ Vitest
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: ⚡ Run vitest
- run: npm run test -- --coverage
-
- playwright:
- name: 🎭 Playwright
- runs-on: ubuntu-22.04
- timeout-minutes: 60
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 📥 Install Playwright Browsers
- run: npm run test:e2e:install
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🏦 Cache Database
- id: db-cache
- uses: actions/cache@v4
- with:
- path: prisma/data.db
- key:
- db-cache-schema_${{ hashFiles('./prisma/schema.prisma')
- }}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql')
- }}
-
- - name: 🌱 Seed Database
- if: steps.db-cache.outputs.cache-hit != 'true'
- run: npx prisma migrate reset --force
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🎭 Playwright tests
- run: npx playwright test
-
- - name: 📊 Upload report
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
-
- container:
- name: 📦 Prepare Container
- runs-on: ubuntu-24.04
- # only prepare container on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 50
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 📦 Build Staging Container
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 📦 Build Production Container
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
- --app ${{ steps.app_name.outputs.value }}
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- deploy:
- name: 🚀 Deploy
- runs-on: ubuntu-24.04
- needs: [lint, typecheck, vitest, playwright, container]
- # only deploy on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: '50'
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 🚀 Deploy Staging
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}-staging:${{ github.sha }}" \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 🚀 Deploy Production
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}:${{ github.sha }}"
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
diff --git a/exercises/04.debugging/01.solution.ui-mode/.github/PULL_REQUEST_TEMPLATE.md b/exercises/04.debugging/01.solution.ui-mode/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 84a2084..0000000
--- a/exercises/04.debugging/01.solution.ui-mode/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-## Test Plan
-
-
-
-## Checklist
-
-- [ ] Tests updated
-- [ ] Docs updated
-
-## Screenshots
-
-
diff --git a/exercises/04.debugging/01.solution.ui-mode/.github/workflows/deploy.yml b/exercises/04.debugging/01.solution.ui-mode/.github/workflows/deploy.yml
deleted file mode 100644
index 49cbbad..0000000
--- a/exercises/04.debugging/01.solution.ui-mode/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,229 +0,0 @@
-name: 🚀 Deploy
-on:
- push:
- branches:
- - main
- - dev
- pull_request: {}
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-permissions:
- actions: write
- contents: read
-
-jobs:
- lint:
- name: ⬣ ESLint
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔬 Lint
- run: npm run lint
-
- typecheck:
- name: ʦ TypeScript
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔎 Type check
- run: npm run typecheck --if-present
-
- vitest:
- name: ⚡ Vitest
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: ⚡ Run vitest
- run: npm run test -- --coverage
-
- playwright:
- name: 🎭 Playwright
- runs-on: ubuntu-22.04
- timeout-minutes: 60
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 📥 Install Playwright Browsers
- run: npm run test:e2e:install
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🏦 Cache Database
- id: db-cache
- uses: actions/cache@v4
- with:
- path: prisma/data.db
- key:
- db-cache-schema_${{ hashFiles('./prisma/schema.prisma')
- }}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql')
- }}
-
- - name: 🌱 Seed Database
- if: steps.db-cache.outputs.cache-hit != 'true'
- run: npx prisma migrate reset --force
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🎭 Playwright tests
- run: npx playwright test
-
- - name: 📊 Upload report
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
-
- container:
- name: 📦 Prepare Container
- runs-on: ubuntu-24.04
- # only prepare container on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 50
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 📦 Build Staging Container
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 📦 Build Production Container
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
- --app ${{ steps.app_name.outputs.value }}
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- deploy:
- name: 🚀 Deploy
- runs-on: ubuntu-24.04
- needs: [lint, typecheck, vitest, playwright, container]
- # only deploy on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: '50'
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 🚀 Deploy Staging
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}-staging:${{ github.sha }}" \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 🚀 Deploy Production
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}:${{ github.sha }}"
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
diff --git a/exercises/04.debugging/02.problem.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md b/exercises/04.debugging/02.problem.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 84a2084..0000000
--- a/exercises/04.debugging/02.problem.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-## Test Plan
-
-
-
-## Checklist
-
-- [ ] Tests updated
-- [ ] Docs updated
-
-## Screenshots
-
-
diff --git a/exercises/04.debugging/02.problem.trace-viewer/.github/workflows/deploy.yml b/exercises/04.debugging/02.problem.trace-viewer/.github/workflows/deploy.yml
deleted file mode 100644
index 49cbbad..0000000
--- a/exercises/04.debugging/02.problem.trace-viewer/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,229 +0,0 @@
-name: 🚀 Deploy
-on:
- push:
- branches:
- - main
- - dev
- pull_request: {}
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-permissions:
- actions: write
- contents: read
-
-jobs:
- lint:
- name: ⬣ ESLint
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔬 Lint
- run: npm run lint
-
- typecheck:
- name: ʦ TypeScript
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔎 Type check
- run: npm run typecheck --if-present
-
- vitest:
- name: ⚡ Vitest
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: ⚡ Run vitest
- run: npm run test -- --coverage
-
- playwright:
- name: 🎭 Playwright
- runs-on: ubuntu-22.04
- timeout-minutes: 60
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 📥 Install Playwright Browsers
- run: npm run test:e2e:install
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🏦 Cache Database
- id: db-cache
- uses: actions/cache@v4
- with:
- path: prisma/data.db
- key:
- db-cache-schema_${{ hashFiles('./prisma/schema.prisma')
- }}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql')
- }}
-
- - name: 🌱 Seed Database
- if: steps.db-cache.outputs.cache-hit != 'true'
- run: npx prisma migrate reset --force
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🎭 Playwright tests
- run: npx playwright test
-
- - name: 📊 Upload report
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
-
- container:
- name: 📦 Prepare Container
- runs-on: ubuntu-24.04
- # only prepare container on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 50
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 📦 Build Staging Container
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 📦 Build Production Container
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
- --app ${{ steps.app_name.outputs.value }}
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- deploy:
- name: 🚀 Deploy
- runs-on: ubuntu-24.04
- needs: [lint, typecheck, vitest, playwright, container]
- # only deploy on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: '50'
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 🚀 Deploy Staging
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}-staging:${{ github.sha }}" \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 🚀 Deploy Production
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}:${{ github.sha }}"
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
diff --git a/exercises/04.debugging/02.solution.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md b/exercises/04.debugging/02.solution.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 84a2084..0000000
--- a/exercises/04.debugging/02.solution.trace-viewer/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-## Test Plan
-
-
-
-## Checklist
-
-- [ ] Tests updated
-- [ ] Docs updated
-
-## Screenshots
-
-
diff --git a/exercises/04.debugging/02.solution.trace-viewer/.github/workflows/deploy.yml b/exercises/04.debugging/02.solution.trace-viewer/.github/workflows/deploy.yml
deleted file mode 100644
index 49cbbad..0000000
--- a/exercises/04.debugging/02.solution.trace-viewer/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,229 +0,0 @@
-name: 🚀 Deploy
-on:
- push:
- branches:
- - main
- - dev
- pull_request: {}
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-permissions:
- actions: write
- contents: read
-
-jobs:
- lint:
- name: ⬣ ESLint
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔬 Lint
- run: npm run lint
-
- typecheck:
- name: ʦ TypeScript
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🔎 Type check
- run: npm run typecheck --if-present
-
- vitest:
- name: ⚡ Vitest
- runs-on: ubuntu-22.04
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: ⚡ Run vitest
- run: npm run test -- --coverage
-
- playwright:
- name: 🎭 Playwright
- runs-on: ubuntu-22.04
- timeout-minutes: 60
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
-
- - name: 🏄 Copy test env vars
- run: cp .env.example .env
-
- - name: ⎔ Setup node
- uses: actions/setup-node@v4
- with:
- node-version: 22
-
- - name: 📥 Download deps
- uses: bahmutov/npm-install@v1
-
- - name: 📥 Install Playwright Browsers
- run: npm run test:e2e:install
-
- - name: 🛠 Setup Database
- run: npx prisma migrate deploy && npx prisma generate --sql
-
- - name: 🏦 Cache Database
- id: db-cache
- uses: actions/cache@v4
- with:
- path: prisma/data.db
- key:
- db-cache-schema_${{ hashFiles('./prisma/schema.prisma')
- }}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql')
- }}
-
- - name: 🌱 Seed Database
- if: steps.db-cache.outputs.cache-hit != 'true'
- run: npx prisma migrate reset --force
-
- - name: 🏗 Build
- run: npm run build
-
- - name: 🎭 Playwright tests
- run: npx playwright test
-
- - name: 📊 Upload report
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: playwright-report
- path: playwright-report/
- retention-days: 30
-
- container:
- name: 📦 Prepare Container
- runs-on: ubuntu-24.04
- # only prepare container on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 50
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 📦 Build Staging Container
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 📦 Build Production Container
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --build-only \
- --push \
- --image-label ${{ github.sha }} \
- --build-arg COMMIT_SHA=${{ github.sha }} \
- --build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
- --app ${{ steps.app_name.outputs.value }}
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- deploy:
- name: 🚀 Deploy
- runs-on: ubuntu-24.04
- needs: [lint, typecheck, vitest, playwright, container]
- # only deploy on pushes
- if: ${{ github.event_name == 'push' }}
- steps:
- - name: ⬇️ Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: '50'
-
- - name: 👀 Read app name
- uses: SebRollen/toml-action@v1.2.0
- id: app_name
- with:
- file: 'fly.toml'
- field: 'app'
-
- - name: 🎈 Setup Fly
- uses: superfly/flyctl-actions/setup-flyctl@1.5
-
- - name: 🚀 Deploy Staging
- if: ${{ github.ref == 'refs/heads/dev' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}-staging:${{ github.sha }}" \
- --app ${{ steps.app_name.outputs.value }}-staging
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
-
- - name: 🚀 Deploy Production
- if: ${{ github.ref == 'refs/heads/main' }}
- run: |
- flyctl deploy \
- --image "registry.fly.io/${{ steps.app_name.outputs.value }}:${{ github.sha }}"
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
diff --git a/exercises/04.debugging/02.solution.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts b/exercises/04.debugging/02.solution.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts
deleted file mode 100644
index 643e453..0000000
--- a/exercises/04.debugging/02.solution.trace-viewer/app/routes/_auth+/auth.$provider.callback.test.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-import { invariant } from '@epic-web/invariant'
-import { faker } from '@faker-js/faker'
-import { SetCookie } from '@mjackson/headers'
-import { http } from 'msw'
-import { afterEach, expect, test } from 'vitest'
-import { twoFAVerificationType } from '#app/routes/settings+/profile.two-factor.tsx'
-import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
-import { GITHUB_PROVIDER_NAME } from '#app/utils/connections.tsx'
-import { prisma } from '#app/utils/db.server.ts'
-import { authSessionStorage } from '#app/utils/session.server.ts'
-import { generateTOTP } from '#app/utils/totp.server.ts'
-import { createUser } from '#tests/db-utils.ts'
-import { insertGitHubUser, deleteGitHubUsers } from '#tests/mocks/github.ts'
-import { server } from '#tests/mocks/index.ts'
-import { consoleError } from '#tests/setup/setup-test-env.ts'
-import { BASE_URL, convertSetCookieToCookie } from '#tests/utils.ts'
-import { loader } from './auth.$provider.callback.ts'
-
-const ROUTE_PATH = '/auth/github/callback'
-const PARAMS = { provider: 'github' }
-
-afterEach(async () => {
- await deleteGitHubUsers()
-})
-
-test('a new user goes to onboarding', async () => {
- const request = await setupRequest()
- const response = await loader({ request, params: PARAMS, context: {} }).catch(
- (e) => e,
- )
- expect(response).toHaveRedirect('/onboarding/github')
-})
-
-test('when auth fails, send the user to login with a toast', async () => {
- consoleError.mockImplementation(() => {})
- server.use(
- http.post('https://github.com/login/oauth/access_token', async () => {
- return new Response(null, { status: 400 })
- }),
- )
- const request = await setupRequest()
- const response = await loader({ request, params: PARAMS, context: {} }).catch(
- (e) => e,
- )
- invariant(response instanceof Response, 'response should be a Response')
- expect(response).toHaveRedirect('/login')
- await expect(response).toSendToast(
- expect.objectContaining({
- title: 'Auth Failed',
- type: 'error',
- }),
- )
- expect(consoleError).toHaveBeenCalledTimes(1)
-})
-
-test('when a user is logged in, it creates the connection', async () => {
- const githubUser = await insertGitHubUser()
- const session = await setupUser()
- const request = await setupRequest({
- sessionId: session.id,
- code: githubUser.code,
- })
- const response = await loader({ request, params: PARAMS, context: {} })
- expect(response).toHaveRedirect('/settings/profile/connections')
- await expect(response).toSendToast(
- expect.objectContaining({
- title: 'Connected',
- type: 'success',
- description: expect.stringContaining(githubUser.profile.login),
- }),
- )
- const connection = await prisma.connection.findFirst({
- select: { id: true },
- where: {
- userId: session.userId,
- providerId: githubUser.profile.id.toString(),
- },
- })
- expect(
- connection,
- 'the connection was not created in the database',
- ).toBeTruthy()
-})
-
-test(`when a user is logged in and has already connected, it doesn't do anything and just redirects the user back to the connections page`, async () => {
- const session = await setupUser()
- const githubUser = await insertGitHubUser()
- await prisma.connection.create({
- data: {
- providerName: GITHUB_PROVIDER_NAME,
- userId: session.userId,
- providerId: githubUser.profile.id.toString(),
- },
- })
- const request = await setupRequest({
- sessionId: session.id,
- code: githubUser.code,
- })
- const response = await loader({ request, params: PARAMS, context: {} })
- expect(response).toHaveRedirect('/settings/profile/connections')
- await expect(response).toSendToast(
- expect.objectContaining({
- title: 'Already Connected',
- description: expect.stringContaining(githubUser.profile.login),
- }),
- )
-})
-
-test('when a user exists with the same email, create connection and make session', async () => {
- const githubUser = await insertGitHubUser()
- const email = githubUser.primaryEmail.toLowerCase()
- const { userId } = await setupUser({ ...createUser(), email })
- const request = await setupRequest({ code: githubUser.code })
- const response = await loader({ request, params: PARAMS, context: {} })
-
- expect(response).toHaveRedirect('/')
-
- await expect(response).toSendToast(
- expect.objectContaining({
- type: 'message',
- description: expect.stringContaining(githubUser.profile.login),
- }),
- )
-
- const connection = await prisma.connection.findFirst({
- select: { id: true },
- where: {
- userId: userId,
- providerId: githubUser.profile.id.toString(),
- },
- })
- expect(
- connection,
- 'the connection was not created in the database',
- ).toBeTruthy()
-
- await expect(response).toHaveSessionForUser(userId)
-})
-
-test('gives an error if the account is already connected to another user', async () => {
- const githubUser = await insertGitHubUser()
- await prisma.user.create({
- data: {
- ...createUser(),
- connections: {
- create: {
- providerName: GITHUB_PROVIDER_NAME,
- providerId: githubUser.profile.id.toString(),
- },
- },
- },
- })
- const session = await setupUser()
- const request = await setupRequest({
- sessionId: session.id,
- code: githubUser.code,
- })
- const response = await loader({ request, params: PARAMS, context: {} })
- expect(response).toHaveRedirect('/settings/profile/connections')
- await expect(response).toSendToast(
- expect.objectContaining({
- title: 'Already Connected',
- description: expect.stringContaining(
- 'already connected to another account',
- ),
- }),
- )
-})
-
-test('if a user is not logged in, but the connection exists, make a session', async () => {
- const githubUser = await insertGitHubUser()
- const { userId } = await setupUser()
- await prisma.connection.create({
- data: {
- providerName: GITHUB_PROVIDER_NAME,
- providerId: githubUser.profile.id.toString(),
- userId,
- },
- })
- const request = await setupRequest({ code: githubUser.code })
- const response = await loader({ request, params: PARAMS, context: {} })
- expect(response).toHaveRedirect('/')
- await expect(response).toHaveSessionForUser(userId)
-})
-
-test('if a user is not logged in, but the connection exists and they have enabled 2FA, send them to verify their 2FA and do not make a session', async () => {
- const githubUser = await insertGitHubUser()
- const { userId } = await setupUser()
- await prisma.connection.create({
- data: {
- providerName: GITHUB_PROVIDER_NAME,
- providerId: githubUser.profile.id.toString(),
- userId,
- },
- })
- const { otp: _otp, ...config } = await generateTOTP()
- await prisma.verification.create({
- data: {
- type: twoFAVerificationType,
- target: userId,
- ...config,
- },
- })
- const request = await setupRequest({ code: githubUser.code })
- const response = await loader({ request, params: PARAMS, context: {} })
- const searchParams = new URLSearchParams({
- type: twoFAVerificationType,
- target: userId,
- redirectTo: '/',
- })
- expect(response).toHaveRedirect(`/verify?${searchParams}`)
-})
-
-async function setupRequest({
- sessionId,
- code = faker.string.uuid(),
-}: { sessionId?: string; code?: string } = {}) {
- const url = new URL(ROUTE_PATH, BASE_URL)
- const state = faker.string.uuid()
- url.searchParams.set('state', state)
- url.searchParams.set('code', code)
- const authSession = await authSessionStorage.getSession()
- if (sessionId) authSession.set(sessionKey, sessionId)
- const setSessionCookieHeader =
- await authSessionStorage.commitSession(authSession)
- const searchParams = new URLSearchParams({ code, state })
- let authCookie = new SetCookie({
- name: 'github',
- value: searchParams.toString(),
- path: '/',
- sameSite: 'Lax',
- httpOnly: true,
- maxAge: 60 * 10,
- secure: process.env.NODE_ENV === 'production' || undefined,
- })
- const request = new Request(url.toString(), {
- method: 'GET',
- headers: {
- cookie: [
- authCookie.toString(),
- convertSetCookieToCookie(setSessionCookieHeader),
- ].join('; '),
- },
- })
- return request
-}
-
-async function setupUser(userData = createUser()) {
- const session = await prisma.session.create({
- data: {
- expirationDate: getSessionExpirationDate(),
- user: {
- create: {
- ...userData,
- },
- },
- },
- select: {
- id: true,
- userId: true,
- },
- })
-
- return session
-}
diff --git a/exercises/04.debugging/02.solution.trace-viewer/app/routes/users+/$username.test.tsx b/exercises/04.debugging/02.solution.trace-viewer/app/routes/users+/$username.test.tsx
deleted file mode 100644
index b0784bd..0000000
--- a/exercises/04.debugging/02.solution.trace-viewer/app/routes/users+/$username.test.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @vitest-environment jsdom
- */
-import { faker } from '@faker-js/faker'
-import { render, screen } from '@testing-library/react'
-import { createRoutesStub } from 'react-router'
-import setCookieParser from 'set-cookie-parser'
-import { test } from 'vitest'
-import { loader as rootLoader } from '#app/root.tsx'
-import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
-import { prisma } from '#app/utils/db.server.ts'
-import { authSessionStorage } from '#app/utils/session.server.ts'
-import { createUser, getUserImages } from '#tests/db-utils.ts'
-import { default as UsernameRoute, loader } from './$username.tsx'
-
-test('The user profile when not logged in as self', async () => {
- const userImages = await getUserImages()
- const userImage =
- userImages[faker.number.int({ min: 0, max: userImages.length - 1 })]
- const user = await prisma.user.create({
- select: { id: true, username: true, name: true },
- data: { ...createUser(), image: { create: userImage } },
- })
- const App = createRoutesStub([
- {
- path: '/users/:username',
- Component: UsernameRoute,
- loader,
- HydrateFallback: () =>
-
-
-
- )
-}
-
-function Logo() {
- return (
-
-
- epic
-
-
- notes
-
-
- )
-}
-
-function AppWithProviders() {
- const data = useLoaderData()
- return (
-
-
-
- )
-}
-
-export default AppWithProviders
-
-// this is a last resort error boundary. There's not much useful information we
-// can offer at this level.
-export const ErrorBoundary = GeneralErrorBoundary
diff --git a/exercises/04.debugging/03.solution.live-debugging/app/routes.ts b/exercises/04.debugging/03.solution.live-debugging/app/routes.ts
deleted file mode 100644
index 946ca4a..0000000
--- a/exercises/04.debugging/03.solution.live-debugging/app/routes.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { type RouteConfig } from '@react-router/dev/routes'
-import { remixRoutesOptionAdapter } from '@react-router/remix-routes-option-adapter'
-import { flatRoutes } from 'remix-flat-routes'
-
-export default remixRoutesOptionAdapter((defineRoutes) => {
- return flatRoutes('routes', defineRoutes, {
- ignoredRouteFiles: [
- '.*',
- '**/*.css',
- '**/*.test.{js,jsx,ts,tsx}',
- '**/__*.*',
- // This is for server-side utilities you want to colocate
- // next to your routes without making an additional
- // directory. If you need a route that includes "server" or
- // "client" in the filename, use the escape brackets like:
- // my-route.[server].tsx
- '**/*.server.*',
- '**/*.client.*',
- ],
- })
-}) satisfies RouteConfig
diff --git a/exercises/04.debugging/03.solution.live-debugging/app/routes/$.tsx b/exercises/04.debugging/03.solution.live-debugging/app/routes/$.tsx
deleted file mode 100644
index 791f7e2..0000000
--- a/exercises/04.debugging/03.solution.live-debugging/app/routes/$.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-// This is called a "splat route" and as it's in the root `/app/routes/`
-// directory, it's a catchall. If no other routes match, this one will and we
-// can know that the user is hitting a URL that doesn't exist. By throwing a
-// 404 from the loader, we can force the error boundary to render which will
-// ensure the user gets the right status code and we can display a nicer error
-// message for them than the Remix and/or browser default.
-
-import { Link, useLocation } from 'react-router'
-import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
-import { Icon } from '#app/components/ui/icon.tsx'
-
-export function loader() {
- throw new Response('Not found', { status: 404 })
-}
-
-export function action() {
- throw new Response('Not found', { status: 404 })
-}
-
-export default function NotFound() {
- // due to the loader, this component will never be rendered, but we'll return
- // the error boundary just in case.
- return
-}
-
-export function ErrorBoundary() {
- const location = useLocation()
- return (
- (
-
-
- We're writing to let you know that your Epic Notes email has been
- changed.
-
-
-
-
- If you changed your email address, then you can safely ignore this.
- But if you did not change your email address, then please contact
- support immediately.
-
-
- {otherSessionsCount ? (
-
-
-
- {dc.doubleCheck
- ? `Are you sure?`
- : `Sign out of ${otherSessionsCount} other sessions`}
-
-
-
- ) : (
- This is your only session
- )}
-
- )
-}
-
-async function deleteDataAction({ userId }: ProfileActionArgs) {
- await prisma.user.delete({ where: { id: userId } })
- return redirectWithToast('/', {
- type: 'success',
- title: 'Data Deleted',
- description: 'All of your data has been deleted',
- })
-}
-
-function DeleteData() {
- const dc = useDoubleCheck()
-
- const fetcher = useFetcher()
- return (
-
-
-
-
- {dc.doubleCheck ? `Are you sure?` : `Delete all your data`}
-
-
-
-
-
- You have enabled two-factor authentication.
-
-
-
- Disable 2FA
-
- >
- ) : (
- <>
-
-
- You have not enabled two-factor authentication yet.
-
-
-
- Two factor authentication adds an extra layer of security to your
- account. You will need to enter a code from an authenticator app
- like{' '}
-
- 1Password
- {' '}
- to log in.
-
- If you cannot scan the QR code, you can manually add this account to
- your authenticator app using this code:
-
-
-
- {loaderData.otpUri}
-
-
-
- Once you've added the account, enter the code from your authenticator
- app below. Once you enable 2FA, you will need to enter a code from
- your authenticator app every time you log in or perform important
- actions. Do not lose access to your authenticator app, or you will
- lose access to your account.
-