create-win-project 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/ci/expo.yml +28 -0
- package/ci/laravel.yml +49 -0
- package/ci/nextjs.yml +29 -0
- package/ci/springboot.yml +33 -0
- package/ci/vite.yml +36 -0
- package/compatibility/profiles.json +237 -0
- package/docs/ARCHITECTURE.md +118 -0
- package/docs/CONTENT_MODEL.md +36 -0
- package/docs/DEPENDENCY_MAINTENANCE.md +31 -0
- package/index.js +431 -0
- package/lib/application-shapes.js +95 -0
- package/lib/banner.js +45 -0
- package/lib/catalog.js +343 -0
- package/lib/compatibility.js +116 -0
- package/lib/constants.js +3 -0
- package/lib/doctor.js +45 -0
- package/lib/files.js +158 -0
- package/lib/generator.js +366 -0
- package/lib/interview.js +77 -0
- package/lib/laravel-scaffold.js +3 -0
- package/lib/playbooks.js +172 -0
- package/lib/project-location.js +18 -0
- package/lib/scaffold.js +467 -0
- package/lib/stacks/context.js +27 -0
- package/lib/stacks/contract.js +142 -0
- package/lib/stacks/index.js +8 -0
- package/lib/stacks/laravel/architecture.js +27 -0
- package/lib/stacks/laravel/auth/oidc.js +13 -0
- package/lib/stacks/laravel/auth/public.js +28 -0
- package/lib/stacks/laravel/auth/sanctum.js +14 -0
- package/lib/stacks/laravel/auth/session.js +17 -0
- package/lib/stacks/laravel/composer.js +50 -0
- package/lib/stacks/laravel/generate.js +362 -0
- package/lib/stacks/laravel/index.js +18 -0
- package/lib/stacks/laravel/ui/blade.js +15 -0
- package/lib/stacks/laravel/ui/index.js +29 -0
- package/lib/stacks/laravel/ui/inertia-react.js +35 -0
- package/lib/stacks/laravel/ui/livewire.js +39 -0
- package/lib/stacks/laravel/ui/shared.js +14 -0
- package/lib/stacks/registry.js +42 -0
- package/lib/stacks/shared/contributions.js +25 -0
- package/lib/template.js +62 -0
- package/package.json +49 -0
- package/playbooks/INDEX.md +58 -0
- package/playbooks/capabilities/auth/oidc-resource-server.md +15 -0
- package/playbooks/capabilities/auth/spring-session.md +15 -0
- package/playbooks/capabilities/ci/github-actions.manifest.json +10 -0
- package/playbooks/capabilities/ci/github-actions.md +61 -0
- package/playbooks/capabilities/docker/docker.manifest.json +11 -0
- package/playbooks/capabilities/docker/overview.md +55 -0
- package/playbooks/capabilities/flyway/environments.md +5 -0
- package/playbooks/capabilities/flyway/flyway.manifest.json +12 -0
- package/playbooks/capabilities/flyway/migrations.md +7 -0
- package/playbooks/capabilities/flyway/testing.md +5 -0
- package/playbooks/capabilities/laravel/database.md +8 -0
- package/playbooks/capabilities/laravel/migrations.md +15 -0
- package/playbooks/capabilities/laravel/observability.md +8 -0
- package/playbooks/capabilities/laravel/oidc-resource-server.md +10 -0
- package/playbooks/capabilities/laravel/queues.md +8 -0
- package/playbooks/capabilities/laravel/sanctum-spa.md +8 -0
- package/playbooks/capabilities/laravel/scheduler.md +7 -0
- package/playbooks/capabilities/laravel/session-auth.md +8 -0
- package/playbooks/capabilities/laravel/storage-uploads.md +7 -0
- package/playbooks/capabilities/postgresql/architecture.md +5 -0
- package/playbooks/capabilities/postgresql/migrations.md +5 -0
- package/playbooks/capabilities/postgresql/postgresql.manifest.json +15 -0
- package/playbooks/capabilities/postgresql/schema-design.md +7 -0
- package/playbooks/capabilities/postgresql/security.md +5 -0
- package/playbooks/capabilities/postgresql/testing.md +5 -0
- package/playbooks/capabilities/prisma/architecture.md +5 -0
- package/playbooks/capabilities/prisma/migrations.md +11 -0
- package/playbooks/capabilities/prisma/prisma.manifest.json +14 -0
- package/playbooks/capabilities/prisma/runtime.md +5 -0
- package/playbooks/capabilities/prisma/schema.md +5 -0
- package/playbooks/capabilities/prisma/testing.md +5 -0
- package/playbooks/capabilities/supabase/architecture.md +5 -0
- package/playbooks/capabilities/supabase/authentication.md +5 -0
- package/playbooks/capabilities/supabase/expo.md +16 -0
- package/playbooks/capabilities/supabase/migrations.md +7 -0
- package/playbooks/capabilities/supabase/nextjs.md +24 -0
- package/playbooks/capabilities/supabase/rls.md +7 -0
- package/playbooks/capabilities/supabase/supabase.manifest.json +32 -0
- package/playbooks/capabilities/supabase/testing.md +5 -0
- package/playbooks/capabilities/supabase/vite.md +14 -0
- package/playbooks/concerns/axios.md +123 -0
- package/playbooks/concerns/next-safe-action.md +66 -0
- package/playbooks/concerns/next-themes.md +87 -0
- package/playbooks/concerns/nuqs.md +59 -0
- package/playbooks/concerns/t3-env.md +48 -0
- package/playbooks/concerns/tanstack-query.md +145 -0
- package/playbooks/concerns/zod.md +174 -0
- package/playbooks/concerns/zustand.md +93 -0
- package/playbooks/devops/makefile.manifest.json +10 -0
- package/playbooks/devops/makefile.md +556 -0
- package/playbooks/devops/pr-template.manifest.json +10 -0
- package/playbooks/devops/pr-template.md +106 -0
- package/playbooks/platform/laravel-ui/blade/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/blade/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/blade/security.md +5 -0
- package/playbooks/platform/laravel-ui/blade/structure.md +5 -0
- package/playbooks/platform/laravel-ui/blade/testing.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/security.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/structure.md +5 -0
- package/playbooks/platform/laravel-ui/inertia-react/testing.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/architecture.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/runtime.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/security.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/structure.md +5 -0
- package/playbooks/platform/laravel-ui/livewire/testing.md +5 -0
- package/playbooks/platform/mobile.manifest.json +17 -0
- package/playbooks/platform/mobile.md +15 -0
- package/playbooks/platform/web.manifest.json +17 -0
- package/playbooks/platform/web.md +17 -0
- package/playbooks/stack/expo/architecture.md +27 -0
- package/playbooks/stack/expo/runtime.md +14 -0
- package/playbooks/stack/expo/security.md +18 -0
- package/playbooks/stack/expo/structure.md +26 -0
- package/playbooks/stack/expo/testing.md +13 -0
- package/playbooks/stack/laravel/architecture.md +34 -0
- package/playbooks/stack/laravel/runtime.md +27 -0
- package/playbooks/stack/laravel/security.md +23 -0
- package/playbooks/stack/laravel/structure.md +29 -0
- package/playbooks/stack/laravel/testing.md +22 -0
- package/playbooks/stack/laravel-ui.manifest.json +42 -0
- package/playbooks/stack/laravel.manifest.json +35 -0
- package/playbooks/stack/nextjs/architecture.md +62 -0
- package/playbooks/stack/nextjs/runtime.md +31 -0
- package/playbooks/stack/nextjs/security.md +32 -0
- package/playbooks/stack/nextjs/structure.md +50 -0
- package/playbooks/stack/nextjs/testing.md +20 -0
- package/playbooks/stack/nextjs.manifest.json +49 -0
- package/playbooks/stack/no-frontend.manifest.json +25 -0
- package/playbooks/stack/none.manifest.json +21 -0
- package/playbooks/stack/react-native.manifest.json +49 -0
- package/playbooks/stack/react-vite/architecture.md +33 -0
- package/playbooks/stack/react-vite/runtime.md +13 -0
- package/playbooks/stack/react-vite/security.md +16 -0
- package/playbooks/stack/react-vite/structure.md +23 -0
- package/playbooks/stack/react-vite/testing.md +12 -0
- package/playbooks/stack/react-vite.manifest.json +46 -0
- package/playbooks/stack/springboot/architecture.md +40 -0
- package/playbooks/stack/springboot/runtime.md +28 -0
- package/playbooks/stack/springboot/security.md +28 -0
- package/playbooks/stack/springboot/structure.md +30 -0
- package/playbooks/stack/springboot/testing.md +22 -0
- package/playbooks/stack/springboot.manifest.json +38 -0
- package/playbooks/styling/css-modules-extensions.md +267 -0
- package/playbooks/styling/css-modules.manifest.json +11 -0
- package/playbooks/styling/native-styles.manifest.json +9 -0
- package/playbooks/styling/native-styles.md +29 -0
- package/playbooks/styling/tailwind-extensions.md +182 -0
- package/playbooks/styling/tailwind.manifest.json +11 -0
- package/playbooks/universal/accessibility.manifest.json +11 -0
- package/playbooks/universal/accessibility.md +45 -0
- package/playbooks/universal/coding-rules.manifest.json +12 -0
- package/playbooks/universal/coding-rules.md +281 -0
- package/playbooks/universal/error-handling.manifest.json +10 -0
- package/playbooks/universal/error-handling.md +21 -0
- package/playbooks/universal/git-conventions.manifest.json +10 -0
- package/playbooks/universal/git-conventions.md +186 -0
- package/playbooks/universal/observability.manifest.json +10 -0
- package/playbooks/universal/observability.md +29 -0
- package/playbooks/universal/security.manifest.json +11 -0
- package/playbooks/universal/security.md +30 -0
- package/playbooks/universal/typescript.manifest.json +11 -0
- package/playbooks/universal/typescript.md +272 -0
- package/scripts/compatibility-matrix.mjs +48 -0
- package/scripts/validate-content.mjs +76 -0
- package/scripts/verify-generated.mjs +153 -0
- package/templates/agents/nextjs.md +47 -0
- package/templates/agents/react-native.md +48 -0
- package/templates/agents/react-vite.md +48 -0
- package/templates/docker/compose/postgres.yml +29 -0
- package/templates/docker/compose/springboot.yml +69 -0
- package/templates/docker/compose/supabase.yml +18 -0
- package/templates/docker/compose-prod/springboot.yml +64 -0
- package/templates/docker/dockerfile/laravel-inertia.dev.dockerfile +21 -0
- package/templates/docker/dockerfile/laravel.dev.dockerfile +12 -0
- package/templates/docker/dockerfile/laravel.prod.dockerfile +13 -0
- package/templates/docker/dockerfile/nextjs.dev.dockerfile +6 -0
- package/templates/docker/dockerfile/nextjs.prod.dockerfile +18 -0
- package/templates/docker/dockerfile/springboot.dev.dockerfile +5 -0
- package/templates/docker/dockerfile/springboot.prod.dockerfile +10 -0
- package/templates/docker/dockerfile/vite.dev.dockerfile +6 -0
- package/templates/docker/dockerfile/vite.prod.dockerfile +12 -0
- package/templates/gitignore/base.gitignore +32 -0
- package/templates/gitignore/nextjs.gitignore +40 -0
- package/templates/gitignore/react-native.gitignore +43 -0
- package/templates/gitignore/react-vite.gitignore +39 -0
- package/templates/makefile/frontend.mk +31 -0
- package/templates/makefile/laravel.mk +47 -0
- package/templates/makefile/postgres.mk +40 -0
- package/templates/makefile/springboot.mk +125 -0
- package/templates/makefile/supabase.mk +42 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Inertia React Runtime
|
|
2
|
+
|
|
3
|
+
Use Inertia navigation/forms for Laravel routes and writes. Form Requests remain authoritative;
|
|
4
|
+
React validation is UX only. Keep shared props small, send only necessary fields, use local/URL state
|
|
5
|
+
for browser concerns, and add an API client only for a genuinely external browser-side service.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Inertia React Security
|
|
2
|
+
|
|
3
|
+
Props and browser bundles are public and modifiable. Laravel re-checks Policies/Gates beside every
|
|
4
|
+
operation. Keep CSRF and secure session cookies, avoid broad CORS, allowlist redirects, and never put
|
|
5
|
+
models, hidden fields, reset tokens, credentials, or unnecessary PII into page props.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Inertia React Structure
|
|
2
|
+
|
|
3
|
+
Use `resources/js/pages` for route pages, `features/<name>` for reusable feature UI/hooks/types,
|
|
4
|
+
`components/ui` for primitives, `layouts` for shells, and `lib` for adapters. Laravel-owned page data
|
|
5
|
+
arrives as props; do not generate frontend repositories, stores, services, or API clients by habit.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Inertia React Testing
|
|
2
|
+
|
|
3
|
+
Laravel feature tests prove route middleware, validation, authorization, component selection, safe
|
|
4
|
+
prop shape, redirects, and writes. React Testing Library proves accessible rendering/interactions.
|
|
5
|
+
Playwright covers critical navigation and auth journeys; Large checks public feature imports.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Livewire Architecture
|
|
2
|
+
|
|
3
|
+
Livewire components are server-driven UI adapters. Small may coordinate simple CRUD directly;
|
|
4
|
+
Medium calls Actions/Services for meaningful workflows; Large namespaces components by module and
|
|
5
|
+
enforces boundaries. Public component state is never a trusted domain boundary.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Livewire Runtime
|
|
2
|
+
|
|
3
|
+
Treat synchronized properties, event payloads, route values, and action arguments as untrusted.
|
|
4
|
+
Validate and authorize every callable mutation, keep state small, and put transactions in the called
|
|
5
|
+
application operation. Handle loading, empty, stale, retry, forbidden, and error states deliberately.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Livewire Security
|
|
2
|
+
|
|
3
|
+
Re-authorize every protected component action. Never expose sensitive model fields or secrets in
|
|
4
|
+
public state or markup. Keep framework session/CSRF protections enabled, validate uploads and event
|
|
5
|
+
arguments, throttle abuse-sensitive actions, and treat Alpine/browser JavaScript as untrusted.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Livewire Structure
|
|
2
|
+
|
|
3
|
+
Choose one consistent supported component format. Route-level components own pages; interactive
|
|
4
|
+
components own focused reactive state; Blade components own static reusable markup. Extract Form
|
|
5
|
+
objects only for substantial form state, and align Large namespaces with module ownership.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Livewire Testing
|
|
2
|
+
|
|
3
|
+
Component tests exercise public interactions, validation, authorization, state, upload handling,
|
|
4
|
+
and rendered behavior. Test Actions, Services, Policies, transactions, and queries independently.
|
|
5
|
+
Use Playwright only for critical complete journeys and verify Large module boundaries separately.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "mobile-platform",
|
|
3
|
+
"kind": "platform",
|
|
4
|
+
"label": "Mobile Platform",
|
|
5
|
+
"appliesTo": { "platform": ["mobile"] },
|
|
6
|
+
"deps": [],
|
|
7
|
+
"devDeps": [],
|
|
8
|
+
"env": [],
|
|
9
|
+
"clientEnv": [],
|
|
10
|
+
"constraints": [
|
|
11
|
+
"Treat the installed application as an untrusted public client",
|
|
12
|
+
"Handle foreground, background, offline, and deep-link lifecycle explicitly"
|
|
13
|
+
],
|
|
14
|
+
"concerns": [
|
|
15
|
+
{ "id": "mobile-platform", "required": true, "playbook": "platform/mobile.md", "sections": ["Device Boundary", "Lifecycle and Links"] }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Mobile Platform
|
|
2
|
+
|
|
3
|
+
## Device Boundary
|
|
4
|
+
|
|
5
|
+
An installed application cannot keep a server secret. Ship only public client identifiers; keep authorization and privileged operations on the server or in database policies. Store sessions in platform-protected secure storage, never plain preferences or AsyncStorage.
|
|
6
|
+
|
|
7
|
+
## Lifecycle and Links
|
|
8
|
+
|
|
9
|
+
Bind session refresh, subscriptions, and reconnect behavior to foreground/background lifecycle. Register exact application schemes and universal/app links. Validate every incoming deep link and allow only known destinations.
|
|
10
|
+
|
|
11
|
+
Design remote work for intermittent connectivity, retries, duplicate delivery, and cancellation. Large offline-capable applications require explicit conflict resolution and observable synchronization state.
|
|
12
|
+
|
|
13
|
+
## Device Experience
|
|
14
|
+
|
|
15
|
+
Respect safe areas, text scaling, accessibility roles, reduced motion, permissions, and platform navigation conventions. Test behavior on representative devices; a web export is useful but does not replace native verification.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "web-platform",
|
|
3
|
+
"kind": "platform",
|
|
4
|
+
"label": "Web Platform",
|
|
5
|
+
"appliesTo": { "platform": ["web"] },
|
|
6
|
+
"deps": [],
|
|
7
|
+
"devDeps": [],
|
|
8
|
+
"env": [],
|
|
9
|
+
"clientEnv": [],
|
|
10
|
+
"constraints": [
|
|
11
|
+
"Treat browser code and browser-visible environment variables as public",
|
|
12
|
+
"Preserve semantic HTML, keyboard access, and progressive failure behavior"
|
|
13
|
+
],
|
|
14
|
+
"concerns": [
|
|
15
|
+
{ "id": "web-platform", "required": true, "playbook": "platform/web.md", "sections": ["Browser Boundary", "Navigation and Accessibility"] }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Web Platform
|
|
2
|
+
|
|
3
|
+
## Browser Boundary
|
|
4
|
+
|
|
5
|
+
Anything shipped to the browser is observable and modifiable. Public environment prefixes are configuration, never secret storage. Enforce authentication, resource authorization, validation, and trusted side effects on a server or at the data policy boundary.
|
|
6
|
+
|
|
7
|
+
Use secure, HttpOnly cookies for server-managed sessions. Keep CSRF protection for cookie-authenticated mutations. Token refresh belongs to the selected identity SDK or server session implementation; do not add a competing generic interceptor.
|
|
8
|
+
|
|
9
|
+
## Navigation and Accessibility
|
|
10
|
+
|
|
11
|
+
Use links for navigation and buttons for actions. Preserve focus, keyboard operation, semantic landmarks, labels, loading feedback, and actionable errors. Prefer platform behavior over custom keyboard or history handling.
|
|
12
|
+
|
|
13
|
+
Validate redirect targets against explicit same-origin allowlists. Do not accept arbitrary callback or `next` URLs.
|
|
14
|
+
|
|
15
|
+
## Runtime Failures
|
|
16
|
+
|
|
17
|
+
Model loading, empty, error, offline, unauthorized, and forbidden states explicitly. Cancel obsolete requests where the framework supports it, and do not display success before a trusted boundary confirms the mutation.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Expo Architecture
|
|
2
|
+
|
|
3
|
+
## Profiles
|
|
4
|
+
|
|
5
|
+
### Small
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Expo Router screen → feature component → api/data function → trusted backend
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Medium (default)
|
|
12
|
+
|
|
13
|
+
Features own their components, hooks, API/data functions, runtime schemas, and types.
|
|
14
|
+
Platform session storage and lifecycle adapters remain shared infrastructure. Client
|
|
15
|
+
Services may coordinate device/UI workflows but never replace server authorization.
|
|
16
|
+
|
|
17
|
+
### Large
|
|
18
|
+
|
|
19
|
+
Keep the Medium tree and add explicit feature public APIs, sync/offline policy, background
|
|
20
|
+
tasks, platform adapters, contract tests, and native-device E2E. Add these only when the
|
|
21
|
+
product needs them.
|
|
22
|
+
|
|
23
|
+
## Dependency Direction
|
|
24
|
+
|
|
25
|
+
Routes compose screens. Screens call features. Features call shared platform/transport
|
|
26
|
+
adapters. Transport code never imports navigation or visual components. The backend or
|
|
27
|
+
Supabase RLS remains the trusted policy boundary.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Expo Runtime
|
|
2
|
+
|
|
3
|
+
## Lifecycle and Remote State
|
|
4
|
+
|
|
5
|
+
- Re-evaluate session and stale remote state when the app returns to the foreground.
|
|
6
|
+
- Cancel work that outlives a screen; do not retry writes without idempotency analysis.
|
|
7
|
+
- Design loading, offline, empty, error, retry, and conflict states.
|
|
8
|
+
- Persist only the minimum state that must survive termination.
|
|
9
|
+
- Use route params for navigation state, a query cache for remote state when justified,
|
|
10
|
+
and a client store only for genuinely cross-screen client state.
|
|
11
|
+
- Every `EXPO_PUBLIC_` value is embedded in the application and is not secret.
|
|
12
|
+
|
|
13
|
+
Web export proves bundling, not native correctness. Test Android and iOS behavior before
|
|
14
|
+
release, including permissions, safe areas, text scaling, links, and background changes.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Expo Security
|
|
2
|
+
|
|
3
|
+
## Mobile Trust Boundary
|
|
4
|
+
|
|
5
|
+
The installed application is an untrusted client. Never embed database passwords,
|
|
6
|
+
service-role keys, OAuth client secrets, or signing keys. UI role checks do not authorize
|
|
7
|
+
API or Supabase requests.
|
|
8
|
+
|
|
9
|
+
## Session Storage
|
|
10
|
+
|
|
11
|
+
Use a maintained provider with Authorization Code + PKCE. Store persistent session
|
|
12
|
+
material in SecureStore, never AsyncStorage. The provider owns refresh-token rotation;
|
|
13
|
+
the app handles expiry, revocation, logout, foreground resume, and retry without refresh
|
|
14
|
+
loops. Validate registered deep-link callback schemes and reject arbitrary return URLs.
|
|
15
|
+
|
|
16
|
+
Supabase projects use the generated SecureStore adapter. Spring multi-client projects use
|
|
17
|
+
the chosen OIDC provider; Spring validates access tokens and never receives refresh tokens.
|
|
18
|
+
Redact tokens, recovery links, authorization headers, and personal data from diagnostics.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Expo Structure
|
|
2
|
+
|
|
3
|
+
## Expo Router
|
|
4
|
+
|
|
5
|
+
Routes live in `app/`; `_layout.tsx` composes navigation and installed providers. Validate
|
|
6
|
+
route and deep-link parameters before use. Navigation belongs in screens or explicit user
|
|
7
|
+
action handlers, never deep inside data utilities.
|
|
8
|
+
|
|
9
|
+
## Feature Ownership
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
app/ route files
|
|
13
|
+
features/tasks/
|
|
14
|
+
├── components/
|
|
15
|
+
├── hooks/
|
|
16
|
+
├── api.ts REST protocol, when used
|
|
17
|
+
├── data.ts Supabase access, when used
|
|
18
|
+
├── schema.ts
|
|
19
|
+
└── types.ts
|
|
20
|
+
components/ui/ reusable native primitives
|
|
21
|
+
lib/ transport, secure storage, platform adapters
|
|
22
|
+
config/ validated public runtime configuration
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Create only needed folders. Large features expose an `index.ts` public API and may add
|
|
26
|
+
`sync/`, `background/`, or `platform/` after the corresponding runtime behavior exists.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Expo Testing
|
|
2
|
+
|
|
3
|
+
## Test Layers
|
|
4
|
+
|
|
5
|
+
- Unit-test schemas, state transitions, and pure sync/conflict policies.
|
|
6
|
+
- Use React Native Testing Library for accessible screen behavior.
|
|
7
|
+
- Contract-test API/data functions and offline/error normalization.
|
|
8
|
+
- Test SecureStore through an adapter, never by exposing real session material.
|
|
9
|
+
- Test foreground/background expiry and ensure refresh failures cannot loop.
|
|
10
|
+
- Large projects add native-device E2E for critical flows.
|
|
11
|
+
|
|
12
|
+
Every profile passes typecheck, Jest, `expo install --check`, and web export. These checks
|
|
13
|
+
do not replace Android and iOS release verification.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Laravel Architecture
|
|
2
|
+
|
|
3
|
+
## Profiles
|
|
4
|
+
|
|
5
|
+
### Small
|
|
6
|
+
|
|
7
|
+
`Route → Form Request when needed → Controller → Eloquent → Resource/View`.
|
|
8
|
+
Use Laravel conventions directly. Do not add Actions, Services, repositories, or DTO
|
|
9
|
+
folders for trivial CRUD.
|
|
10
|
+
|
|
11
|
+
### Medium (Recommended)
|
|
12
|
+
|
|
13
|
+
`Route → Form Request → Controller/UI adapter → Action or Service → Eloquent`.
|
|
14
|
+
An Action owns one meaningful use case. A Service owns a reusable capability shared by
|
|
15
|
+
several use cases. The coordinating operation owns multi-write transactions.
|
|
16
|
+
|
|
17
|
+
### Large
|
|
18
|
+
|
|
19
|
+
Keep the Medium vocabulary inside a modular monolith. Modules expose small public APIs
|
|
20
|
+
and keep application, domain, persistence, jobs, and UI adapters private. Enforce module
|
|
21
|
+
dependencies automatically. Large does not mean repository-per-model or microservices.
|
|
22
|
+
|
|
23
|
+
## Dependency Direction
|
|
24
|
+
|
|
25
|
+
HTTP, CLI, jobs, and UI components call application behavior. Application behavior may
|
|
26
|
+
use Eloquent or an explicit external adapter; it never depends on controllers, requests,
|
|
27
|
+
Blade, Livewire, or Inertia.
|
|
28
|
+
|
|
29
|
+
## Escalation
|
|
30
|
+
|
|
31
|
+
Eloquent is the default persistence abstraction. Add a repository or query object only
|
|
32
|
+
for complex repeated queries, multiple data sources, or a boundary with measurable value.
|
|
33
|
+
Create a directory only with its first real file.
|
|
34
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Laravel Runtime
|
|
2
|
+
|
|
3
|
+
## Request Lifecycle
|
|
4
|
+
|
|
5
|
+
Validate untrusted input with Form Requests, authorize the resource and operation, invoke
|
|
6
|
+
application behavior, then return an intentional Resource, DTO, redirect, or view. Never
|
|
7
|
+
serialize a complete Eloquent model accidentally.
|
|
8
|
+
|
|
9
|
+
## Transactions and Side Effects
|
|
10
|
+
|
|
11
|
+
The application operation coordinating related writes owns the transaction. Dispatch
|
|
12
|
+
jobs and listeners after commit when they depend on committed state. Use idempotency and
|
|
13
|
+
an outbox when cross-system delivery must survive process failure.
|
|
14
|
+
|
|
15
|
+
## Queries
|
|
16
|
+
|
|
17
|
+
Load relationships intentionally, prevent N+1 behavior, validate pagination, and allowlist
|
|
18
|
+
filter and sorting fields. Database constraints remain authoritative under races.
|
|
19
|
+
|
|
20
|
+
## Configuration and Failures
|
|
21
|
+
|
|
22
|
+
Read server configuration through Laravel config, fail safely when required values are
|
|
23
|
+
missing, and never expose secrets to browser assets. Map expected failures to stable safe
|
|
24
|
+
responses; unexpected failures receive a trace identifier and server-side diagnostics.
|
|
25
|
+
|
|
26
|
+
Use Composer, Artisan, the generated npm scripts, and Pint. Never edit `vendor/`.
|
|
27
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Laravel Security
|
|
2
|
+
|
|
3
|
+
## Trust Boundaries
|
|
4
|
+
|
|
5
|
+
Form Request validation is not authorization. Enforce Gates/Policies beside every
|
|
6
|
+
protected read or side effect, including resource ownership; hiding UI is never enough.
|
|
7
|
+
Guard mass assignment and return intentional Resources/props/view data.
|
|
8
|
+
|
|
9
|
+
## Authentication Models
|
|
10
|
+
|
|
11
|
+
- Laravel-owned Blade, Livewire, and Inertia sites use secure server sessions and CSRF.
|
|
12
|
+
- A separate first-party SPA on the same parent domain uses Sanctum stateful cookies.
|
|
13
|
+
- Independent mobile/multi-client APIs validate access tokens from an external OIDC
|
|
14
|
+
provider; that provider owns issuance, refresh, rotation, and revocation.
|
|
15
|
+
- Sanctum personal access tokens are credentials, not a refresh-token system.
|
|
16
|
+
- Passport is opt-in only when the product truly operates an OAuth2 server.
|
|
17
|
+
|
|
18
|
+
Cookie settings, CORS origins, redirect destinations, and callback URLs are explicit
|
|
19
|
+
allowlists. Throttle login, recovery, uploads, and abuse-sensitive mutations. Uploaded
|
|
20
|
+
files are untrusted and require type, size, ownership, storage, and download controls.
|
|
21
|
+
|
|
22
|
+
Never log passwords, cookies, bearer tokens, reset links, secrets, or unnecessary PII.
|
|
23
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Laravel Structure
|
|
2
|
+
|
|
3
|
+
## Package by Feature
|
|
4
|
+
|
|
5
|
+
Keep Laravel's conventional entry points and group meaningful application behavior by
|
|
6
|
+
feature when the codebase grows.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
app/
|
|
10
|
+
├── Http/Controllers/ # HTTP coordination
|
|
11
|
+
├── Http/Requests/ # trust-boundary validation
|
|
12
|
+
├── Http/Resources/ # intentional API shapes
|
|
13
|
+
├── Models/ # Eloquent models
|
|
14
|
+
├── Policies/ # resource authorization
|
|
15
|
+
├── Actions/ # real named use cases only
|
|
16
|
+
├── Services/ # shared capabilities only
|
|
17
|
+
└── Jobs/ # real background work only
|
|
18
|
+
database/{migrations,factories,seeders}/
|
|
19
|
+
routes/{web,api}.php
|
|
20
|
+
tests/{Feature,Unit}/
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Small generates only conventional files required by its example. Medium adds an Action
|
|
24
|
+
or Service only for a real workflow. Large aligns namespaces with modules and exposes an
|
|
25
|
+
explicit public module API. Repositories, Queries, DTOs, Events, and Jobs remain
|
|
26
|
+
demand-driven in every profile.
|
|
27
|
+
|
|
28
|
+
Never create empty placeholder trees. Use normal Laravel and PSR naming conventions.
|
|
29
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Laravel Testing
|
|
2
|
+
|
|
3
|
+
## Risk-Based Layers
|
|
4
|
+
|
|
5
|
+
| Risk | Test |
|
|
6
|
+
|---|---|
|
|
7
|
+
| Pure PHP/domain rule | Pest/PHPUnit unit test |
|
|
8
|
+
| Validation, middleware, Resource contract | HTTP feature test |
|
|
9
|
+
| Policy/resource ownership | unauthenticated, forbidden, allowed tests |
|
|
10
|
+
| Eloquent query or migration | target PostgreSQL integration test |
|
|
11
|
+
| Queue dispatch/retry | focused job test plus integrated boundary test |
|
|
12
|
+
| Browser behavior | component test or Playwright critical journey |
|
|
13
|
+
| Large module dependency | automated architecture check |
|
|
14
|
+
|
|
15
|
+
Use factories for intent and `RefreshDatabase` with an isolated test database. SQLite may
|
|
16
|
+
support fast framework-independent tests, but it is not evidence for PostgreSQL-specific
|
|
17
|
+
SQL, constraints, locking, or migrations.
|
|
18
|
+
|
|
19
|
+
Test safe failures, conflicts, transaction rollback, login/logout, session expiry, CSRF,
|
|
20
|
+
and resource authorization according to the selected authentication model. Do not mock
|
|
21
|
+
Eloquent merely to satisfy a unit-test percentage.
|
|
22
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "laravel-ui", "kind": "frontend", "label": "Laravel full-stack UI", "platform": "web",
|
|
3
|
+
"appliesTo": { "backend": ["laravel"] }, "port": 8000, "needsDocker": false, "frontendDir": "",
|
|
4
|
+
"architectureProfiles": ["small", "medium", "large"],
|
|
5
|
+
"playbooks": [
|
|
6
|
+
{ "file": "platform/laravel-ui/blade/architecture.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
7
|
+
{ "file": "platform/laravel-ui/blade/structure.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
8
|
+
{ "file": "platform/laravel-ui/blade/runtime.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
9
|
+
{ "file": "platform/laravel-ui/blade/security.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
10
|
+
{ "file": "platform/laravel-ui/blade/testing.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
11
|
+
{ "file": "platform/laravel-ui/livewire/architecture.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
12
|
+
{ "file": "platform/laravel-ui/livewire/structure.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
13
|
+
{ "file": "platform/laravel-ui/livewire/runtime.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
14
|
+
{ "file": "platform/laravel-ui/livewire/security.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
15
|
+
{ "file": "platform/laravel-ui/livewire/testing.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
16
|
+
{ "file": "platform/laravel-ui/inertia-react/architecture.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
17
|
+
{ "file": "platform/laravel-ui/inertia-react/structure.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
18
|
+
{ "file": "platform/laravel-ui/inertia-react/runtime.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
19
|
+
{ "file": "platform/laravel-ui/inertia-react/security.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
20
|
+
{ "file": "platform/laravel-ui/inertia-react/testing.md", "appliesWhen": { "laravelUi": "inertia-react" } }
|
|
21
|
+
],
|
|
22
|
+
"stylingOptions": ["tailwind"], "scripts": {}, "ciTemplate": "none", "envPrefix": "VITE_",
|
|
23
|
+
"folders": [], "deps": [], "devDeps": [], "env": [], "clientEnv": [],
|
|
24
|
+
"constraints": ["Laravel owns routing, authentication, authorization, and persistence"],
|
|
25
|
+
"concerns": [
|
|
26
|
+
{ "id": "ui-architecture", "required": true, "playbook": "platform/laravel-ui/blade/architecture.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
27
|
+
{ "id": "ui-structure", "required": true, "playbook": "platform/laravel-ui/blade/structure.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
28
|
+
{ "id": "ui-runtime", "required": true, "playbook": "platform/laravel-ui/blade/runtime.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
29
|
+
{ "id": "ui-security", "required": true, "playbook": "platform/laravel-ui/blade/security.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
30
|
+
{ "id": "ui-testing", "required": true, "playbook": "platform/laravel-ui/blade/testing.md", "appliesWhen": { "laravelUi": "blade" } },
|
|
31
|
+
{ "id": "ui-architecture", "required": true, "playbook": "platform/laravel-ui/livewire/architecture.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
32
|
+
{ "id": "ui-structure", "required": true, "playbook": "platform/laravel-ui/livewire/structure.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
33
|
+
{ "id": "ui-runtime", "required": true, "playbook": "platform/laravel-ui/livewire/runtime.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
34
|
+
{ "id": "ui-security", "required": true, "playbook": "platform/laravel-ui/livewire/security.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
35
|
+
{ "id": "ui-testing", "required": true, "playbook": "platform/laravel-ui/livewire/testing.md", "appliesWhen": { "laravelUi": "livewire" } },
|
|
36
|
+
{ "id": "ui-architecture", "required": true, "playbook": "platform/laravel-ui/inertia-react/architecture.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
37
|
+
{ "id": "ui-structure", "required": true, "playbook": "platform/laravel-ui/inertia-react/structure.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
38
|
+
{ "id": "ui-runtime", "required": true, "playbook": "platform/laravel-ui/inertia-react/runtime.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
39
|
+
{ "id": "ui-security", "required": true, "playbook": "platform/laravel-ui/inertia-react/security.md", "appliesWhen": { "laravelUi": "inertia-react" } },
|
|
40
|
+
{ "id": "ui-testing", "required": true, "playbook": "platform/laravel-ui/inertia-react/testing.md", "appliesWhen": { "laravelUi": "inertia-react" } }
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "laravel",
|
|
3
|
+
"kind": "backend",
|
|
4
|
+
"label": "Laravel (PHP)",
|
|
5
|
+
"appliesTo": { "frontend": ["nextjs", "react", "react-native", "no-frontend", "laravel-ui"] },
|
|
6
|
+
"port": 8000,
|
|
7
|
+
"needsDocker": true,
|
|
8
|
+
"makefileTemplate": "laravel",
|
|
9
|
+
"architectureProfiles": ["small", "medium", "large"],
|
|
10
|
+
"playbooks": [
|
|
11
|
+
"stack/laravel/architecture.md",
|
|
12
|
+
"stack/laravel/structure.md",
|
|
13
|
+
"stack/laravel/runtime.md",
|
|
14
|
+
"stack/laravel/security.md",
|
|
15
|
+
"stack/laravel/testing.md",
|
|
16
|
+
"capabilities/laravel/database.md",
|
|
17
|
+
"capabilities/laravel/migrations.md",
|
|
18
|
+
{ "file": "capabilities/laravel/session-auth.md", "appliesWhen": { "authentication": "laravel-session" } },
|
|
19
|
+
{ "file": "capabilities/laravel/sanctum-spa.md", "appliesWhen": { "authentication": "sanctum-spa" } },
|
|
20
|
+
{ "file": "capabilities/laravel/oidc-resource-server.md", "appliesWhen": { "authentication": "laravel-oidc" } }
|
|
21
|
+
],
|
|
22
|
+
"folders": [], "deps": [], "devDeps": [],
|
|
23
|
+
"env": ["DATABASE_URL", "POSTGRES_USER", "POSTGRES_PASSWORD", "POSTGRES_DB", "APP_KEY", "APP_URL"],
|
|
24
|
+
"clientEnv": [],
|
|
25
|
+
"constraints": [
|
|
26
|
+
"Laravel owns trusted server behavior and resource authorization",
|
|
27
|
+
"PostgreSQL migrations are the generated schema source of truth"
|
|
28
|
+
],
|
|
29
|
+
"concerns": [
|
|
30
|
+
{ "id": "architecture", "required": true, "playbook": "stack/laravel/architecture.md", "sections": ["Profiles", "Dependency Direction"] },
|
|
31
|
+
{ "id": "stack-security", "required": true, "playbook": "stack/laravel/security.md", "sections": ["Trust Boundaries", "Authentication Models"] },
|
|
32
|
+
{ "id": "stack-testing", "required": true, "playbook": "stack/laravel/testing.md", "sections": ["Risk-Based Layers"] },
|
|
33
|
+
{ "id": "migrations", "required": true, "playbook": "capabilities/laravel/migrations.md", "sections": ["Development", "Production"] }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Next.js Architecture
|
|
2
|
+
|
|
3
|
+
## Profiles
|
|
4
|
+
|
|
5
|
+
The selected profile is a baseline for the project, not permission to create empty layers.
|
|
6
|
+
|
|
7
|
+
### Small
|
|
8
|
+
|
|
9
|
+
Keep routing and route composition in `src/app`. A route may call a feature query or
|
|
10
|
+
server-only data function directly. A Server Function may perform a simple validated
|
|
11
|
+
mutation directly through the secure data-access boundary. Do not create a Service for
|
|
12
|
+
trivial mapping or a Repository without persistence.
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
Server Component → Query/DAL → owned data
|
|
16
|
+
Form → Server Function → DAL → owned data
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Medium (default)
|
|
20
|
+
|
|
21
|
+
Group application code by feature. Entry points call a reusable Service when an
|
|
22
|
+
operation contains policy, coordination, or is shared. Reads use feature Queries.
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
Web Action ──────┐
|
|
26
|
+
Route Handler ───┼──→ Service → Repository → Next-owned database
|
|
27
|
+
Job ─────────────┘
|
|
28
|
+
|
|
29
|
+
Page → Query → Repository → Next-owned database
|
|
30
|
+
Page/Action → Service when useful → API client → Spring or external API
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
A Repository means owned persistence. A remote HTTP client belongs in `api/`; do not
|
|
34
|
+
rename transport code to make every diagram look identical.
|
|
35
|
+
|
|
36
|
+
### Large
|
|
37
|
+
|
|
38
|
+
Keep the Medium vocabulary. Add an explicit feature public API, domain policies where
|
|
39
|
+
real domain behavior exists, jobs/events, contract tests, observability, and automated
|
|
40
|
+
cross-feature import checks. Large means enforced boundaries, not extra synonyms for
|
|
41
|
+
Service and Repository.
|
|
42
|
+
|
|
43
|
+
## Dependency Direction
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
app routing → feature entry points/UI → application operations → data/API boundary
|
|
47
|
+
shared UI → no feature imports
|
|
48
|
+
feature A → feature B public API only (Large)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- `app/` owns URLs, layouts, metadata, loading, errors, and composition.
|
|
52
|
+
- Actions and Route Handlers are untrusted entry points, not business operations.
|
|
53
|
+
- Services do not import React components or route modules.
|
|
54
|
+
- Repositories and API clients do not import UI.
|
|
55
|
+
- Do not duplicate the same operation across Actions, handlers, and jobs.
|
|
56
|
+
|
|
57
|
+
## Escalation Rules
|
|
58
|
+
|
|
59
|
+
Add a Service for meaningful rules, multi-step coordination, reuse, transactions, or
|
|
60
|
+
independent testing. Add a Repository when Next owns persistence. Add a domain policy
|
|
61
|
+
when behavior has a stable business name and invariants. Never add a folder only because
|
|
62
|
+
the selected profile lists it.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Next.js Runtime
|
|
2
|
+
|
|
3
|
+
## Server and Client
|
|
4
|
+
|
|
5
|
+
Server Components are the default. Add `'use client'` only for state, effects, event
|
|
6
|
+
handlers, browser APIs, or client-only libraries, and keep that boundary narrow.
|
|
7
|
+
|
|
8
|
+
- Read initial data directly on the server; do not fetch the app's own HTTP route.
|
|
9
|
+
- Keep database clients, secret environment variables, and privileged SDKs server-only.
|
|
10
|
+
- Treat every `NEXT_PUBLIC_` value as public.
|
|
11
|
+
- Route Handlers exist for real HTTP consumers such as mobile apps, webhooks, and third
|
|
12
|
+
parties—not as mandatory internal indirection.
|
|
13
|
+
|
|
14
|
+
## Caching and Mutations
|
|
15
|
+
|
|
16
|
+
Caching is an explicit data decision. Document whether a read is request memoized,
|
|
17
|
+
cross-request cached, revalidated, or dynamic. After a mutation, invalidate the narrowest
|
|
18
|
+
tag or path that represents the changed data. Never cache permission checks or mutable
|
|
19
|
+
user-specific results without a reviewed key and lifetime.
|
|
20
|
+
|
|
21
|
+
Server Functions are public server entry points even when their call sites are internal.
|
|
22
|
+
They validate input, authenticate and authorize, call an operation, invalidate affected
|
|
23
|
+
data, and return a small serializable result.
|
|
24
|
+
|
|
25
|
+
## Configuration and Failures
|
|
26
|
+
|
|
27
|
+
- Validate required environment variables at startup/build boundaries.
|
|
28
|
+
- Use `loading.tsx`, Suspense, and error boundaries where their scope is meaningful.
|
|
29
|
+
- Log structured server events with request/trace identifiers; never log credentials,
|
|
30
|
+
cookies, authorization headers, reset links, or full personal objects.
|
|
31
|
+
- Production builds, lint, typecheck, and tests are part of the runtime contract.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Next.js Security
|
|
2
|
+
|
|
3
|
+
## Authorization
|
|
4
|
+
|
|
5
|
+
Proxy and layouts may make optimistic navigation decisions, but secure authorization is
|
|
6
|
+
performed again in every Server Function, Route Handler, DAL/Repository, or protected
|
|
7
|
+
side effect. Check both the authenticated principal and access to the requested resource.
|
|
8
|
+
|
|
9
|
+
Treat Server Functions as public endpoints. Validate runtime input and return DTOs with
|
|
10
|
+
only fields the caller may receive. Never pass whole database entities into Client
|
|
11
|
+
Components.
|
|
12
|
+
|
|
13
|
+
## Sessions
|
|
14
|
+
|
|
15
|
+
Session behavior is selected by the authentication capability:
|
|
16
|
+
|
|
17
|
+
- Supabase SSR uses cookie-aware clients and Proxy-driven refresh with `getClaims()`.
|
|
18
|
+
- A Spring-backed browser session is owned by Spring; Next acts as UI/BFF and does not
|
|
19
|
+
invent a second refresh-token protocol.
|
|
20
|
+
- OIDC access tokens come from the identity provider; the resource API validates them.
|
|
21
|
+
- `not-yet` means no login exists. Do not add fake role flags or trusted client state.
|
|
22
|
+
|
|
23
|
+
Cookies carrying credentials must be `HttpOnly`, `Secure` in production, and use an
|
|
24
|
+
appropriate `SameSite` policy. Cookie-authenticated writes require CSRF protection.
|
|
25
|
+
Validate every redirect/return path as an application-relative destination.
|
|
26
|
+
|
|
27
|
+
## Server Boundaries
|
|
28
|
+
|
|
29
|
+
- Use `server-only` for repositories, admin clients, and secret configuration.
|
|
30
|
+
- Never expose a service-role key, database URL, refresh token, or private API key.
|
|
31
|
+
- Rate limit expensive and abuse-sensitive public operations at a trusted boundary.
|
|
32
|
+
- Add security headers deliberately; CSP must match the assets and scripts actually used.
|