create-projx 0.1.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.
@@ -0,0 +1,146 @@
1
+ services:
2
+ <% if (components.includes('fastapi')) { %>
3
+ migrate:
4
+ build: ./fastapi
5
+ command: ['uv', 'run', 'migrate.py']
6
+ env_file:
7
+ - ./fastapi/.env
8
+ deploy:
9
+ resources:
10
+ limits:
11
+ memory: 256M
12
+ cpus: '0.5'
13
+ networks:
14
+ - app-network
15
+
16
+ backend:
17
+ build: ./fastapi
18
+ expose:
19
+ - '7860'
20
+ env_file:
21
+ - ./fastapi/.env
22
+ restart: unless-stopped
23
+ depends_on:
24
+ migrate:
25
+ condition: service_completed_successfully
26
+ healthcheck:
27
+ test:
28
+ [
29
+ 'CMD',
30
+ 'python',
31
+ '-c',
32
+ "import urllib.request; urllib.request.urlopen('http://localhost:7860/api/health')",
33
+ ]
34
+ interval: 30s
35
+ timeout: 10s
36
+ retries: 3
37
+ start_period: 15s
38
+ deploy:
39
+ resources:
40
+ limits:
41
+ memory: 512M
42
+ cpus: '1.0'
43
+ reservations:
44
+ memory: 256M
45
+ security_opt:
46
+ - no-new-privileges:true
47
+ read_only: true
48
+ tmpfs:
49
+ - /tmp
50
+ networks:
51
+ - app-network
52
+ <% } %>
53
+ <% if (components.includes('fastify')) { %>
54
+ backend-fastify:
55
+ build: ./fastify
56
+ expose:
57
+ - '3000'
58
+ env_file:
59
+ - ./fastify/.env
60
+ restart: unless-stopped
61
+ healthcheck:
62
+ test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:3000/api/health']
63
+ interval: 30s
64
+ timeout: 10s
65
+ retries: 3
66
+ start_period: 15s
67
+ deploy:
68
+ resources:
69
+ limits:
70
+ memory: 512M
71
+ cpus: '1.0'
72
+ security_opt:
73
+ - no-new-privileges:true
74
+ networks:
75
+ - app-network
76
+ <% } %>
77
+ <% if (components.includes('frontend')) { %>
78
+ frontend:
79
+ build:
80
+ context: ./frontend
81
+ args:
82
+ VITE_API_URL: ''
83
+ ports:
84
+ - '80:80'
85
+ - '443:443'
86
+ environment:
87
+ - DOMAIN=${DOMAIN:-localhost}
88
+ volumes:
89
+ - letsencrypt:/etc/letsencrypt
90
+ - certbot-www:/var/www/certbot
91
+ <% if (components.includes('fastapi')) { %>
92
+ depends_on:
93
+ backend:
94
+ condition: service_healthy
95
+ <% } %>
96
+ <% if (components.includes('fastify') && !components.includes('fastapi')) { %>
97
+ depends_on:
98
+ backend-fastify:
99
+ condition: service_healthy
100
+ <% } %>
101
+ restart: unless-stopped
102
+ healthcheck:
103
+ test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:80/']
104
+ interval: 30s
105
+ timeout: 5s
106
+ retries: 3
107
+ start_period: 10s
108
+ deploy:
109
+ resources:
110
+ limits:
111
+ memory: 128M
112
+ cpus: '0.5'
113
+ security_opt:
114
+ - no-new-privileges:true
115
+ networks:
116
+ - app-network
117
+
118
+ certbot:
119
+ image: certbot/certbot:latest
120
+ volumes:
121
+ - letsencrypt:/etc/letsencrypt
122
+ - certbot-www:/var/www/certbot
123
+ entrypoint: /bin/sh -c "trap exit TERM; while :; do certbot renew --quiet; sleep 12h & wait $${!}; done"
124
+ restart: unless-stopped
125
+ depends_on:
126
+ frontend:
127
+ condition: service_healthy
128
+ profiles:
129
+ - ssl
130
+ deploy:
131
+ resources:
132
+ limits:
133
+ memory: 64M
134
+ cpus: '0.25'
135
+ networks:
136
+ - app-network
137
+ <% } %>
138
+ <% if (components.includes('frontend')) { %>
139
+ volumes:
140
+ letsencrypt:
141
+ certbot-www:
142
+ <% } %>
143
+
144
+ networks:
145
+ app-network:
146
+ driver: bridge
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # ── Secret detection ──────────────────────────────────────────────
5
+ STAGED_DIFF="$(git diff --cached --diff-filter=ACMR)"
6
+
7
+ if echo "$STAGED_DIFF" | grep -qE '(AKIA|ASIA)[A-Z0-9]{16}'; then
8
+ echo "ERROR: Possible AWS access key detected in staged changes."
9
+ exit 1
10
+ fi
11
+
12
+ if echo "$STAGED_DIFF" | grep -qE '(password|secret|token)\s*[:=]\s*["\x27][^"'\'']{8,}' 2>/dev/null; then
13
+ REAL_SECRETS="$(echo "$STAGED_DIFF" | grep -E '(password|secret|token)\s*[:=]\s*["\x27][^"'\'']{8,}' | grep -vE '(test-secret|dev-secret|example|placeholder|your-|changeme|CHANGE_ME)' || true)"
14
+ if [ -n "$REAL_SECRETS" ]; then
15
+ echo "WARNING: Possible secret detected in staged changes:"
16
+ echo "$REAL_SECRETS" | head -5
17
+ echo "If intentional, commit with: git commit --no-verify"
18
+ exit 1
19
+ fi
20
+ fi
21
+
22
+ STAGED_ENV_FILES="$(git diff --cached --name-only --diff-filter=ACMR | grep -E '^(\.env$|.*\/\.env$|.*\.env\.(prod|staging|dev)$)' || true)"
23
+ if [ -n "$STAGED_ENV_FILES" ]; then
24
+ echo "ERROR: .env file(s) staged for commit:"
25
+ echo "$STAGED_ENV_FILES"
26
+ exit 1
27
+ fi
28
+
29
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
30
+ <% if (components.includes('fastapi')) { %>
31
+
32
+ FASTAPI_PY=$(echo "$STAGED_FILES" | grep '^fastapi/.*\.py$' || true)
33
+ if [ -n "$FASTAPI_PY" ]; then
34
+ echo "Formatting & linting fastapi..."
35
+ cd fastapi
36
+ echo "$FASTAPI_PY" | sed 's|^fastapi/||' | xargs uv run ruff format
37
+ echo "$FASTAPI_PY" | sed 's|^fastapi/||' | xargs uv run ruff check --fix
38
+ cd ..
39
+ echo "$FASTAPI_PY" | xargs git add
40
+ fi
41
+ <% } %>
42
+ <% if (components.includes('fastify')) { %>
43
+
44
+ FASTIFY_TS=$(echo "$STAGED_FILES" | grep '^fastify/.*\.ts$' || true)
45
+ FASTIFY_ALL=$(echo "$STAGED_FILES" | grep '^fastify/' || true)
46
+ if [ -n "$FASTIFY_ALL" ]; then
47
+ echo "Formatting fastify..."
48
+ cd fastify
49
+ echo "$FASTIFY_ALL" | sed 's|^fastify/||' | xargs npx prettier --write --ignore-unknown
50
+ if [ -n "$FASTIFY_TS" ]; then
51
+ echo "$FASTIFY_TS" | sed 's|^fastify/||' | xargs npx eslint --fix
52
+ npx tsc --noEmit
53
+ fi
54
+ cd ..
55
+ echo "$FASTIFY_ALL" | xargs git add
56
+ fi
57
+ <% } %>
58
+ <% if (components.includes('frontend')) { %>
59
+
60
+ FRONTEND_TS=$(echo "$STAGED_FILES" | grep '^frontend/.*\.tsx\?$' || true)
61
+ FRONTEND_ALL=$(echo "$STAGED_FILES" | grep '^frontend/' || true)
62
+ if [ -n "$FRONTEND_ALL" ]; then
63
+ echo "Formatting frontend..."
64
+ cd frontend
65
+ echo "$FRONTEND_ALL" | sed 's|^frontend/||' | xargs npx prettier --write --ignore-unknown
66
+ if [ -n "$FRONTEND_TS" ]; then
67
+ echo "$FRONTEND_TS" | sed 's|^frontend/||' | xargs npx eslint --fix
68
+ npx tsc --noEmit
69
+ fi
70
+ cd ..
71
+ echo "$FRONTEND_ALL" | xargs git add
72
+ fi
73
+ <% } %>
74
+ <% if (components.includes('e2e')) { %>
75
+
76
+ E2E_TS=$(echo "$STAGED_FILES" | grep '^e2e/.*\.ts$' || true)
77
+ E2E_ALL=$(echo "$STAGED_FILES" | grep '^e2e/' || true)
78
+ if [ -n "$E2E_ALL" ]; then
79
+ echo "Formatting e2e..."
80
+ cd e2e
81
+ echo "$E2E_ALL" | sed 's|^e2e/||' | xargs npx prettier --write --ignore-unknown
82
+ if [ -n "$E2E_TS" ]; then
83
+ echo "$E2E_TS" | sed 's|^e2e/||' | xargs npx eslint --fix
84
+ npx tsc --noEmit
85
+ fi
86
+ cd ..
87
+ echo "$E2E_ALL" | xargs git add
88
+ fi
89
+ <% } %>
90
+ <% if (components.includes('mobile')) { %>
91
+
92
+ MOBILE_DART=$(echo "$STAGED_FILES" | grep '^mobile/.*\.dart$' || true)
93
+ if [ -n "$MOBILE_DART" ]; then
94
+ if command -v dart &> /dev/null; then
95
+ echo "Formatting mobile..."
96
+ cd mobile
97
+ echo "$MOBILE_DART" | sed 's|^mobile/||' | xargs dart format
98
+ if command -v flutter &> /dev/null; then
99
+ dart analyze --fatal-infos
100
+ fi
101
+ cd ..
102
+ echo "$MOBILE_DART" | xargs git add
103
+ else
104
+ echo "Skipping mobile lint (dart not installed)"
105
+ fi
106
+ fi
107
+ <% } %>
108
+ <% if (components.includes('infra')) { %>
109
+
110
+ INFRA_TF=$(echo "$STAGED_FILES" | grep '^infra/.*\.tf$' || true)
111
+ if [ -n "$INFRA_TF" ]; then
112
+ if command -v terraform &> /dev/null; then
113
+ echo "Formatting infra..."
114
+ cd infra/stack
115
+ echo "$INFRA_TF" | sed 's|^infra/stack/||' | xargs terraform fmt
116
+ cd ../..
117
+ echo "$INFRA_TF" | xargs git add
118
+ else
119
+ echo "Skipping infra lint (terraform not installed)"
120
+ fi
121
+ fi
122
+ <% } %>
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ git config core.hooksPath .githooks
5
+ echo "Git hooks configured."
6
+ <% if (components.includes('fastapi')) { %>
7
+
8
+ cd fastapi && uv sync --all-extras && cd ..
9
+ echo "FastAPI dependencies installed."
10
+ <% } %>
11
+ <% if (components.includes('fastify')) { %>
12
+
13
+ cd fastify && pnpm install --frozen-lockfile && cd ..
14
+ echo "Fastify dependencies installed."
15
+ <% } %>
16
+ <% if (components.includes('frontend')) { %>
17
+
18
+ cd frontend && npm ci && cd ..
19
+ echo "Frontend dependencies installed."
20
+ <% } %>
21
+ <% if (components.includes('e2e')) { %>
22
+
23
+ cd e2e && npm ci && cd ..
24
+ echo "E2E dependencies installed."
25
+ <% } %>
26
+ <% if (components.includes('mobile')) { %>
27
+
28
+ if command -v flutter &>/dev/null; then
29
+ cd mobile && flutter pub get && cd ..
30
+ echo "Flutter dependencies installed."
31
+ else
32
+ echo "Flutter SDK not installed — skipping mobile."
33
+ fi
34
+ <% } %>
35
+
36
+ echo ""
37
+ echo "Done. Run 'make run-dev' to start, or 'make help' for all commands."