forgedev 1.4.0 → 1.4.1

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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/chainproof-bridge.js +9 -2
  3. package/src/ci-mode.js +3 -4
  4. package/src/composer.js +228 -242
  5. package/src/doctor-checks-chainproof.js +14 -11
  6. package/src/doctor-checks.js +3 -19
  7. package/src/index.js +6 -34
  8. package/src/recommender.js +319 -319
  9. package/src/uat-generator.js +105 -93
  10. package/src/utils.js +245 -214
  11. package/templates/auth/jwt-custom/backend/app/api/auth.py.template +39 -45
  12. package/templates/auth/jwt-custom/backend/app/core/security.py.template +44 -37
  13. package/templates/backend/express/package.json.template +35 -33
  14. package/templates/backend/express/src/lib/prisma.ts.template +32 -0
  15. package/templates/backend/express/src/routes/health.ts.template +35 -27
  16. package/templates/backend/fastapi/backend/app/main.py.template +67 -60
  17. package/templates/backend/fastapi/backend/requirements.txt.template +18 -16
  18. package/templates/backend/hono/package.json.template +33 -31
  19. package/templates/backend/hono/src/lib/prisma.ts.template +32 -0
  20. package/templates/backend/hono/src/routes/health.ts.template +38 -27
  21. package/templates/base/.gitignore.template +32 -32
  22. package/templates/claude-code/commands/workflows.md +52 -52
  23. package/templates/database/prisma-postgres/prisma/schema.prisma.template +19 -18
  24. package/templates/database/sqlalchemy-postgres/backend/alembic/env.py.template +39 -40
  25. package/templates/database/sqlalchemy-postgres/backend/alembic.ini.template +38 -36
  26. package/templates/database/sqlalchemy-postgres/backend/app/db/session.py.template +50 -48
  27. package/templates/frontend/nextjs/package.json.template +45 -43
  28. package/templates/frontend/remix/package.json.template +41 -39
  29. package/templates/infra/docker/.dockerignore.template +16 -0
  30. package/templates/infra/docker-compose/docker-compose.yml.template +22 -19
  31. package/templates/infra/github-actions/.github/workflows/ci.yml.template +61 -52
  32. package/templates/infra/k8s/k8s/deployment.yml.template +70 -70
  33. package/templates/infra/k8s/k8s/hpa.yml.template +24 -24
  34. package/templates/infra/k8s/k8s/ingress.yml.template +26 -26
  35. package/templates/infra/k8s/k8s/kustomization.yml.template +13 -13
  36. package/templates/infra/k8s/k8s/namespace.yml.template +4 -4
  37. package/templates/infra/k8s/k8s/networkpolicy.yml.template +41 -41
  38. package/templates/infra/k8s/k8s/secrets.yml.template +10 -10
  39. package/templates/infra/k8s/k8s/service.yml.template +15 -15
  40. package/templates/testing/load/k6/README.md.template +48 -48
  41. package/templates/testing/load/k6/load-test.js.template +57 -57
@@ -1,52 +1,52 @@
1
- Show the developer what workflows are available.
2
-
3
- ## Available Workflows
4
-
5
- ### Development
6
- - `/plan` - Create an implementation plan before writing code
7
- - `/tdd` - Write failing tests first, then implement (test-driven development)
8
- - `/build-fix` - Fix build, lint, and type errors incrementally
9
- - `/fix-loop` - Automated fix-review-regression loop until green
10
- - `/build-ui` - Build frontend UI with AI-powered generation (Google Stitch + UI UX Pro Max)
11
- - `/code-review` - Review changes for security and quality (required before commit)
12
- - `/simplify` - Find duplicate code, long files, and extract shared utilities
13
-
14
- ### Daily
15
- - `/help` - Not sure what to do? This guides you to the right workflow
16
- - `/status` - Run all checks and show a project dashboard
17
- - `/next` - Figure out what to work on next
18
-
19
- ### Verification
20
- - `/verify-all` - Run lint, type check, tests, then launch all reviewers
21
- - `/full-audit` - Run every audit and review agent in a single pass
22
- - `/audit-spec` - Validate implementation against a spec/PRD
23
- - `/audit-wiring` - Find dead or unwired features
24
- - `/audit-security` - Run a security audit
25
- - `/verify-intent` - Verify all agents comply with Intent Verification Protocol
26
-
27
- ### Strategy
28
- - Use `product-strategist` agent - Research competitors, evaluate project maturity, recommend improvements
29
-
30
- ### Release
31
- - `/pre-pr` - Prepare and create a pull request
32
- - `/run-uat` - Execute UAT scenarios
33
- - `/live-uat` - Run live UAT by interacting with the running application
34
-
35
- ### Generation
36
- - `/generate-prd` - Generate a PRD from the current codebase
37
- - `/generate-sdd` - Generate a Software Design Document from the codebase
38
- - `/generate-uat` - Generate UAT scenarios and checklists
39
- - `/optimize-claude-md` - Slim down an oversized CLAUDE.md
40
-
41
- ### Session
42
- - `/save-session` - Save current work context for later resumption
43
- - `/resume-session` - Load a saved session and continue where you left off
44
-
45
- ## Quality Gates (automatic)
46
-
47
- These run automatically, you don't need to remember them:
48
- - **On commit**: Pre-commit gate runs lint, tests, secrets check, and requires code review
49
- - **On stop**: Code hygiene check runs automatically
50
-
51
- ## Quick Start
52
- Run `/status` to see where things stand, then `/next` to pick up work.
1
+ Show the developer what workflows are available.
2
+
3
+ ## Available Workflows
4
+
5
+ ### Development
6
+ - `/plan` - Create an implementation plan before writing code
7
+ - `/tdd` - Write failing tests first, then implement (test-driven development)
8
+ - `/build-fix` - Fix build, lint, and type errors incrementally
9
+ - `/fix-loop` - Automated fix-review-regression loop until green
10
+ - `/build-ui` - Build frontend UI with AI-powered generation (Google Stitch + UI UX Pro Max)
11
+ - `/code-review` - Review changes for security and quality (required before commit)
12
+ - `/simplify` - Find duplicate code, long files, and extract shared utilities
13
+
14
+ ### Daily
15
+ - `/help` - Not sure what to do? This guides you to the right workflow
16
+ - `/status` - Run all checks and show a project dashboard
17
+ - `/next` - Figure out what to work on next
18
+
19
+ ### Verification
20
+ - `/verify-all` - Run lint, type check, tests, then launch all reviewers
21
+ - `/full-audit` - Run every audit and review agent in a single pass
22
+ - `/audit-spec` - Validate implementation against a spec/PRD
23
+ - `/audit-wiring` - Find dead or unwired features
24
+ - `/audit-security` - Run a security audit
25
+ - `/verify-intent` - Verify all agents comply with Intent Verification Protocol
26
+
27
+ ### Strategy
28
+ - `/product-strategist` - Research competitors, evaluate project maturity, recommend improvements
29
+
30
+ ### Release
31
+ - `/pre-pr` - Prepare and create a pull request
32
+ - `/run-uat` - Execute UAT scenarios
33
+ - `/live-uat` - Run live UAT by interacting with the running application
34
+
35
+ ### Generation
36
+ - `/generate-prd` - Generate a PRD from the current codebase
37
+ - `/generate-sdd` - Generate a Software Design Document from the codebase
38
+ - `/generate-uat` - Generate UAT scenarios and checklists
39
+ - `/optimize-claude-md` - Slim down an oversized CLAUDE.md
40
+
41
+ ### Session
42
+ - `/save-session` - Save current work context for later resumption
43
+ - `/resume-session` - Load a saved session and continue where you left off
44
+
45
+ ## Quality Gates (automatic)
46
+
47
+ These run automatically, you don't need to remember them:
48
+ - **On commit**: Pre-commit gate runs lint, tests, secrets check, and requires code review
49
+ - **On stop**: Code hygiene check runs automatically
50
+
51
+ ## Quick Start
52
+ Run `/status` to see where things stand, then `/next` to pick up work.
@@ -1,18 +1,19 @@
1
- generator client {
2
- provider = "prisma-client-js"
3
- }
4
-
5
- datasource db {
6
- provider = "postgresql"
7
- url = env("DATABASE_URL")
8
- }
9
-
10
- // Add your models below
11
- // Example:
12
- // model User {
13
- // id String @id @default(cuid())
14
- // email String @unique
15
- // name String?
16
- // createdAt DateTime @default(now())
17
- // updatedAt DateTime @updatedAt
18
- // }
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ // Starting point — modify or remove this model to match your project needs
11
+ model User {
12
+ id String @id @default(cuid())
13
+ email String @unique
14
+ name String?
15
+ createdAt DateTime @default(now())
16
+ updatedAt DateTime @updatedAt
17
+ }
18
+
19
+ // Add additional models below
@@ -1,40 +1,39 @@
1
- import asyncio
2
- from logging.config import fileConfig
3
-
4
- from alembic import context
5
- from sqlalchemy.ext.asyncio import create_async_engine
6
-
7
- from app.core.config import settings
8
- from app.db.base import Base
9
-
10
- config = context.config
11
- if config.config_file_name is not None:
12
- fileConfig(config.config_file_name)
13
-
14
- target_metadata = Base.metadata
15
-
16
-
17
- def run_migrations_offline() -> None:
18
- url = settings.database_url
19
- context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
20
- with context.begin_transaction():
21
- context.run_migrations()
22
-
23
-
24
- def do_run_migrations(connection):
25
- context.configure(connection=connection, target_metadata=target_metadata)
26
- with context.begin_transaction():
27
- context.run_migrations()
28
-
29
-
30
- async def run_migrations_online() -> None:
31
- connectable = create_async_engine(settings.database_url)
32
- async with connectable.connect() as connection:
33
- await connection.run_sync(do_run_migrations)
34
- await connectable.dispose()
35
-
36
-
37
- if context.is_offline_mode():
38
- run_migrations_offline()
39
- else:
40
- asyncio.run(run_migrations_online())
1
+ import asyncio
2
+ from logging.config import fileConfig
3
+
4
+ from alembic import context
5
+
6
+ from app.core.config import settings
7
+ from app.db.base import Base
8
+ from app.db.session import engine
9
+
10
+ config = context.config
11
+ if config.config_file_name is not None:
12
+ fileConfig(config.config_file_name)
13
+
14
+ target_metadata = Base.metadata
15
+
16
+
17
+ def run_migrations_offline() -> None:
18
+ url = settings.database_url
19
+ context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
20
+ with context.begin_transaction():
21
+ context.run_migrations()
22
+
23
+
24
+ def do_run_migrations(connection):
25
+ context.configure(connection=connection, target_metadata=target_metadata)
26
+ with context.begin_transaction():
27
+ context.run_migrations()
28
+
29
+
30
+ async def run_migrations_online() -> None:
31
+ async with engine.connect() as connection:
32
+ await connection.run_sync(do_run_migrations)
33
+ await engine.dispose()
34
+
35
+
36
+ if context.is_offline_mode():
37
+ run_migrations_offline()
38
+ else:
39
+ asyncio.run(run_migrations_online())
@@ -1,36 +1,38 @@
1
- [alembic]
2
- script_location = alembic
3
- sqlalchemy.url = postgresql+asyncpg://postgres:postgres@localhost:5432/{{PROJECT_NAME_SNAKE}}
4
-
5
- [loggers]
6
- keys = root,sqlalchemy,alembic
7
-
8
- [handlers]
9
- keys = console
10
-
11
- [formatters]
12
- keys = generic
13
-
14
- [logger_root]
15
- level = WARN
16
- handlers = console
17
-
18
- [logger_sqlalchemy]
19
- level = WARN
20
- handlers =
21
- qualname = sqlalchemy.engine
22
-
23
- [logger_alembic]
24
- level = INFO
25
- handlers =
26
- qualname = alembic
27
-
28
- [handler_console]
29
- class = StreamHandler
30
- args = (sys.stderr,)
31
- level = NOTSET
32
- formatter = generic
33
-
34
- [formatter_generic]
35
- format = %(levelname)-5.5s [%(name)s] %(message)s
36
- datefmt = %H:%M:%S
1
+ [alembic]
2
+ script_location = alembic
3
+ # Overridden at runtime by env.py see app/db/session.py for connection config
4
+ # Do not put real credentials here; env.py reads from settings.database_url
5
+ sqlalchemy.url = driver://user:pass@localhost/dbname
6
+
7
+ [loggers]
8
+ keys = root,sqlalchemy,alembic
9
+
10
+ [handlers]
11
+ keys = console
12
+
13
+ [formatters]
14
+ keys = generic
15
+
16
+ [logger_root]
17
+ level = WARN
18
+ handlers = console
19
+
20
+ [logger_sqlalchemy]
21
+ level = WARN
22
+ handlers =
23
+ qualname = sqlalchemy.engine
24
+
25
+ [logger_alembic]
26
+ level = INFO
27
+ handlers =
28
+ qualname = alembic
29
+
30
+ [handler_console]
31
+ class = StreamHandler
32
+ args = (sys.stderr,)
33
+ level = NOTSET
34
+ formatter = generic
35
+
36
+ [formatter_generic]
37
+ format = %(levelname)-5.5s [%(name)s] %(message)s
38
+ datefmt = %H:%M:%S
@@ -1,48 +1,50 @@
1
- import asyncio
2
- import logging
3
-
4
- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
5
-
6
- from app.core.config import settings
7
-
8
- logger = logging.getLogger(__name__)
9
-
10
- engine = create_async_engine(
11
- settings.database_url,
12
- echo=settings.debug,
13
- pool_size=5,
14
- max_overflow=10,
15
- pool_pre_ping=True,
16
- )
17
-
18
- async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
19
-
20
-
21
- async def connect_with_retry(
22
- engine, max_retries: int = 3, base_delay: float = 1.0
23
- ) -> None:
24
- """Attempt database connection with exponential backoff."""
25
- for attempt in range(1, max_retries + 1):
26
- try:
27
- async with engine.connect() as conn:
28
- await conn.execute(
29
- __import__("sqlalchemy").text("SELECT 1")
30
- )
31
- logger.info("Database connected successfully")
32
- return
33
- except Exception as e:
34
- if attempt == max_retries:
35
- logger.error(f"Database connection failed after {max_retries} attempts: {e}")
36
- raise
37
- delay = base_delay * (2 ** (attempt - 1))
38
- logger.warning(
39
- f"Database connection attempt {attempt}/{max_retries} failed. "
40
- f"Retrying in {delay:.1f}s..."
41
- )
42
- await asyncio.sleep(delay)
43
-
44
-
45
- async def get_db():
46
- """Dependency for FastAPI endpoints."""
47
- async with async_session() as session:
48
- yield session
1
+ import asyncio
2
+ import logging
3
+
4
+ from sqlalchemy import text
5
+ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
6
+
7
+ from app.core.config import settings
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ engine = create_async_engine(
12
+ settings.database_url,
13
+ echo=settings.debug,
14
+ pool_size=5,
15
+ max_overflow=10,
16
+ pool_pre_ping=True,
17
+ pool_recycle=300, # Recycle connections before cloud provider timeout
18
+ )
19
+
20
+ async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
21
+
22
+
23
+ async def connect_with_retry(
24
+ engine, max_retries: int = 3, base_delay: float = 1.0
25
+ ) -> None:
26
+ """Attempt database connection with exponential backoff."""
27
+ for attempt in range(1, max_retries + 1):
28
+ try:
29
+ async with engine.connect() as conn:
30
+ await conn.execute(
31
+ text("SELECT 1")
32
+ )
33
+ logger.info("Database connected successfully")
34
+ return
35
+ except Exception as e:
36
+ if attempt == max_retries:
37
+ logger.error(f"Database connection failed after {max_retries} attempts: {e}")
38
+ raise
39
+ delay = base_delay * (2 ** (attempt - 1))
40
+ logger.warning(
41
+ f"Database connection attempt {attempt}/{max_retries} failed. "
42
+ f"Retrying in {delay:.1f}s..."
43
+ )
44
+ await asyncio.sleep(delay)
45
+
46
+
47
+ async def get_db():
48
+ """Dependency for FastAPI endpoints."""
49
+ async with async_session() as session:
50
+ yield session
@@ -1,43 +1,45 @@
1
- {
2
- "name": "{{PROJECT_NAME}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "next dev",
7
- "build": "next build",
8
- "start": "next start",
9
- "lint": "eslint .",
10
- "typecheck": "tsc --noEmit",
11
- "test": "vitest run",
12
- "test:watch": "vitest",
13
- "test:e2e": "playwright test",
14
- "db:push": "prisma db push",
15
- "db:studio": "prisma studio",
16
- "db:generate": "prisma generate"
17
- },
18
- "dependencies": {
19
- "next": "^15.3.0",
20
- "react": "^19.1.0",
21
- "react-dom": "^19.1.0",
22
- "@prisma/client": "^6.6.0",
23
- "clsx": "^2.1.1",
24
- "tailwind-merge": "^3.2.0",
25
- "react-markdown": "^9.0.3",
26
- "remark-gfm": "^4.0.0"
27
- },
28
- "devDependencies": {
29
- "typescript": "^5.8.3",
30
- "@types/node": "^22.14.0",
31
- "@types/react": "^19.1.0",
32
- "@types/react-dom": "^19.1.0",
33
- "tailwindcss": "^4.1.3",
34
- "@tailwindcss/postcss": "^4.1.3",
35
- "postcss": "^8.5.3",
36
- "eslint": "^9.25.0",
37
- "eslint-config-next": "^15.3.0",
38
- "prisma": "^6.6.0",
39
- "vitest": "^3.1.1",
40
- "@playwright/test": "^1.52.0",
41
- "@testing-library/react": "^16.3.0"
42
- }
43
- }
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint .",
10
+ "typecheck": "tsc --noEmit",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest",
13
+ "test:e2e": "playwright test",
14
+ "db:push": "prisma db push",
15
+ "db:migrate": "prisma migrate dev",
16
+ "db:migrate:deploy": "prisma migrate deploy",
17
+ "db:studio": "prisma studio",
18
+ "db:generate": "prisma generate"
19
+ },
20
+ "dependencies": {
21
+ "next": "^15.3.0",
22
+ "react": "^19.1.0",
23
+ "react-dom": "^19.1.0",
24
+ "@prisma/client": "^6.6.0",
25
+ "clsx": "^2.1.1",
26
+ "tailwind-merge": "^3.2.0",
27
+ "react-markdown": "^9.0.3",
28
+ "remark-gfm": "^4.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.8.3",
32
+ "@types/node": "^22.14.0",
33
+ "@types/react": "^19.1.0",
34
+ "@types/react-dom": "^19.1.0",
35
+ "tailwindcss": "^4.1.3",
36
+ "@tailwindcss/postcss": "^4.1.3",
37
+ "postcss": "^8.5.3",
38
+ "eslint": "^9.25.0",
39
+ "eslint-config-next": "^15.3.0",
40
+ "prisma": "^6.6.0",
41
+ "vitest": "^3.1.1",
42
+ "@playwright/test": "^1.52.0",
43
+ "@testing-library/react": "^16.3.0"
44
+ }
45
+ }
@@ -1,39 +1,41 @@
1
- {
2
- "name": "{{PROJECT_NAME}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "remix vite:dev",
8
- "build": "remix vite:build",
9
- "start": "remix-serve ./build/server/index.js",
10
- "lint": "eslint .",
11
- "typecheck": "tsc --noEmit",
12
- "test": "vitest run",
13
- "test:watch": "vitest",
14
- "db:push": "prisma db push",
15
- "db:studio": "prisma studio",
16
- "db:generate": "prisma generate"
17
- },
18
- "dependencies": {
19
- "@remix-run/node": "^2.16.0",
20
- "@remix-run/react": "^2.16.0",
21
- "@remix-run/serve": "^2.16.0",
22
- "react": "^19.1.0",
23
- "react-dom": "^19.1.0",
24
- "isbot": "^5.1.0",
25
- "@prisma/client": "^6.6.0"
26
- },
27
- "devDependencies": {
28
- "@remix-run/dev": "^2.16.0",
29
- "typescript": "^5.8.3",
30
- "@types/react": "^19.1.0",
31
- "@types/react-dom": "^19.1.0",
32
- "vite": "^6.3.0",
33
- "tailwindcss": "^4.1.3",
34
- "@tailwindcss/vite": "^4.1.3",
35
- "eslint": "^9.25.0",
36
- "prisma": "^6.6.0",
37
- "vitest": "^3.1.1"
38
- }
39
- }
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "remix vite:dev",
8
+ "build": "remix vite:build",
9
+ "start": "remix-serve ./build/server/index.js",
10
+ "lint": "eslint .",
11
+ "typecheck": "tsc --noEmit",
12
+ "test": "vitest run",
13
+ "test:watch": "vitest",
14
+ "db:push": "prisma db push",
15
+ "db:migrate": "prisma migrate dev",
16
+ "db:migrate:deploy": "prisma migrate deploy",
17
+ "db:studio": "prisma studio",
18
+ "db:generate": "prisma generate"
19
+ },
20
+ "dependencies": {
21
+ "@remix-run/node": "^2.16.0",
22
+ "@remix-run/react": "^2.16.0",
23
+ "@remix-run/serve": "^2.16.0",
24
+ "react": "^19.1.0",
25
+ "react-dom": "^19.1.0",
26
+ "isbot": "^5.1.0",
27
+ "@prisma/client": "^6.6.0"
28
+ },
29
+ "devDependencies": {
30
+ "@remix-run/dev": "^2.16.0",
31
+ "typescript": "^5.8.3",
32
+ "@types/react": "^19.1.0",
33
+ "@types/react-dom": "^19.1.0",
34
+ "vite": "^6.3.0",
35
+ "tailwindcss": "^4.1.3",
36
+ "@tailwindcss/vite": "^4.1.3",
37
+ "eslint": "^9.25.0",
38
+ "prisma": "^6.6.0",
39
+ "vitest": "^3.1.1"
40
+ }
41
+ }
@@ -0,0 +1,16 @@
1
+ node_modules
2
+ npm-debug.log*
3
+ .git
4
+ .gitignore
5
+ .env
6
+ .env.*
7
+ *.md
8
+ !README.md
9
+ tests
10
+ coverage
11
+ .nyc_output
12
+ .vscode
13
+ .idea
14
+ .claude
15
+ docs
16
+ dist
@@ -1,19 +1,22 @@
1
- services:
2
- postgres:
3
- image: postgres:17-alpine
4
- environment:
5
- POSTGRES_DB: {{PROJECT_NAME_SNAKE}}
6
- POSTGRES_USER: postgres
7
- POSTGRES_PASSWORD: postgres
8
- ports:
9
- - "5432:5432"
10
- volumes:
11
- - postgres_data:/var/lib/postgresql/data
12
- healthcheck:
13
- test: ["CMD-SHELL", "pg_isready -U postgres"]
14
- interval: 5s
15
- timeout: 5s
16
- retries: 5
17
-
18
- volumes:
19
- postgres_data:
1
+ # WARNING: Default credentials below are for local development only.
2
+ # For production, use secrets management (e.g. Docker secrets, Vault, or env vars).
3
+ services:
4
+ postgres:
5
+ image: postgres:17-alpine
6
+ shm_size: '256mb'
7
+ environment:
8
+ POSTGRES_DB: {{PROJECT_NAME_SNAKE}}
9
+ POSTGRES_USER: ${POSTGRES_USER:-postgres}
10
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
11
+ ports:
12
+ - "5432:5432"
13
+ volumes:
14
+ - postgres_data:/var/lib/postgresql/data
15
+ healthcheck:
16
+ test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
17
+ interval: 5s
18
+ timeout: 5s
19
+ retries: 5
20
+
21
+ volumes:
22
+ postgres_data: